Java学习笔记必看经典.docx
《Java学习笔记必看经典.docx》由会员分享,可在线阅读,更多相关《Java学习笔记必看经典.docx(17页珍藏版)》请在冰豆网上搜索。
![Java学习笔记必看经典.docx](https://file1.bdocx.com/fileroot1/2023-1/8/d804e717-f123-46be-b4e2-31714ebcd1a0/d804e717-f123-46be-b4e2-31714ebcd1a01.gif)
Java学习笔记必看经典
名词解释&JAVA多线程编程
名词解释:
JNI(JavaNativeInterface)指的是Java本地调用接口,通过这一接口,Java程序可以和采用其他语言编写的本地程序进行通信。
IPC是两个进程之间进行通信的一种机制。
JMX(JavaManagementExtensions)是SUN提出的Java管理扩展规范,是一个为应用程序、设备和系统植入管理功能的框架。
JMX可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议。
通过JMX,用户可以灵活地开发无缝集成的系统、网络和服务管理应用。
JNDI(JavaNamingandDirectoryInterface)是一种将对象和名字绑定的技术,对象工厂负责生产出对象,这些对象都和惟一的名字绑定。
外部程序可以通过名字来获得某个对象的引用。
DTD即文档类型定义。
SMTP(SimpleMailTransferProtocol)即简单邮件传输协议,是Internet传送E-mail的基本协议,也是TCP/IP协议组的成员。
SMTP解决了E-mail系统如何通过一条链路,把邮件从一台机器传递到另一台机器上的问题。
通常把发送邮件服务器称为SMTP服务器。
POP3(PostOfficeProtocol3)即邮局协议第3版,这是Internet接收E-mail的基本协议,也是TCP/IP协议组的成员。
IMAP(InternetMessageAccessProtocol)即直接收取邮件的协议,是与POP3不同的一种E-mail接收的新协议。
MIME(MultipurposeInternetMailExtensions)是一种电子邮件编码方式,它可以将发信人的电子邮件中的文本以及各种附件都打包后发送。
SOAP(SimpleObjectAccessProtocol)即简单对象访问协议,是在分散或分布式的环境中交换信息的简单协议,它以XML作为数据传送方式。
OOP即面向对象程序设计
OOA(ObjectOrientedAnalysis)即面向对象的分析。
OOD(ObjectOrientedDesign)即面向对象的设计。
OOI(ObjectOrientedImplementation)即面向对象的实现。
GUI(GraphicsUserInterface)图形用户界面或图形用户接口。
IFC(InternetFoundationClasser)Internet基本类。
JFC(JavaFoundationClasser)Java基本类。
AWT(AbstractWindowToolkit)抽象窗口工具箱
JAVA多线程编程
synchronized关键字(记下来,很重要)。
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。
另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
四、第三个例子同样适用其它同步代码块。
也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。
结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
五、以上规则对其它对象锁同样适用.
举例说明:
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。
另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
packageths;
publicclassThread1implementsRunnable{
publicvoidrun(){
synchronized(this){
for(inti=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+"synchronizedloop"+i);
}
}
}
publicstaticvoidmain(String[]args){
Thread1t1=newThread1();
Threadta=newThread(t1,"A");
Threadtb=newThread(t1,"B");
ta.start();
tb.start();
}
}
结果:
Asynchronizedloop0
Asynchronizedloop1
Asynchronizedloop2
Asynchronizedloop3
Asynchronizedloop4
Bsynchronizedloop0
Bsynchronizedloop1
Bsynchronizedloop2
Bsynchronizedloop3
Bsynchronizedloop4
二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
packageths;
publicclassThread2{
publicvoidm4t1(){
synchronized(this){
inti=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+":
"+i);
try{
Thread.sleep(500);
}catch(InterruptedExceptionie){
}
}
}
}
publicvoidm4t2(){
inti=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+":
"+i);
try{
Thread.sleep(500);
}catch(InterruptedExceptionie){
}
}
}
publicstaticvoidmain(String[]args){
finalThread2myt2=newThread2();
Threadt1=newThread( newRunnable(){ publicvoidrun(){ myt2.m4t1(); } },"t1" );
Threadt2=newThread( newRunnable(){ publicvoidrun(){myt2.m4t2(); } },"t2" );
t1.start();
t2.start();
}
}
结果:
t1:
4
t2:
4
t1:
3
t2:
3
t1:
2
t2:
2
t1:
1
t2:
1
t1:
0
t2:
0
三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
//修改Thread2.m4t2()方法:
publicvoidm4t2(){
synchronized(this){
inti=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+":
"+i);
try{
Thread.sleep(500);
}catch(InterruptedExceptionie){
}
}
}
}
结果:
t1:
4
t1:
3
t1:
2
t1:
1
t1:
0
t2:
4
t2:
3
t2:
2
t2:
1
t2:
0
四、第三个例子同样适用其它同步代码块。
也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。
结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
//修改Thread2.m4t2()方法如下:
publicsynchronizedvoidm4t2(){
inti=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+":
"+i);
try{
Thread.sleep(500);
}catch(InterruptedExceptionie){
}
}
}
结果:
t1:
4
t1:
3
t1:
2
t1:
1
t1:
0
t2:
4
t2:
3
t2:
2
t2:
1
t2:
0
五、以上规则对其它对象锁同样适用:
packageths;
publicclassThread3{
classInner{
privatevoidm4t1(){
inti=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+":
Inner.m4t1()="+i);
try{
Thread.sleep(500);
}catch(InterruptedExceptionie){
}
}
}
privatevoidm4t2(){
inti=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+":
Inner.m4t2()="+i);
try{
Thread.sleep(500);
}catch(InterruptedExceptionie){
}
}
}
}
privatevoidm4t1(Innerinner){
synchronized(inner){//使用对象锁
inner.m4t1();
}
privatevoidm4t2(Innerinner){
inner.m4t2();
}
publicstaticvoidmain(String[]args){
finalThread3myt3=newThread3();
finalInnerinner=myt3.newInner();
Threadt1=newThread(newRunnable(){publicvoidrun(){myt3.m4t1(inner);}},"t1");
Threadt2=newThread(newRunnable(){publicvoidrun(){myt3.m4t2(inner);}},"t2");
t1.start();
t2.start();
}
}
结果:
尽管线程t1获得了对Inner的对象锁,但由于线程t2访问的是同一个Inner中的非同步部分。
所以两个线程互不干扰。
t1:
Inner.m4t1()=4
t2:
Inner.m4t2()=4
t1:
Inner.m4t1()=3
t2:
Inner.m4t2()=3
t1:
Inner.m4t1()=2
t2:
Inner.m4t2()=2
t1:
Inner.m4t1()=1
t2:
Inner.m4t2()=1
t1:
Inner.m4t1()=0
t2:
Inner.m4t2()=0
现在在Inner.m4t2()前面加上synchronized:
privatesynchronizedvoidm4t2(){
inti=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+":
Inner.m4t2()="+i);
try{
Thread.sleep(500);
}catch(InterruptedExceptionie){
}
}
}
结果:
尽管线程t1与t2访问了同一个Inner对象中两个毫不相关的部分,但因为t1先获得了对Inner的对象锁,所以t2对Inner.m4t2()的访问也被阻塞,因为m4t2()是Inner中的一个同步方法。
t1:
Inner.m4t1()=4
t1:
Inner.m4t1()=3
t1:
Inner.m4t1()=2
t1:
Inner.m4t1()=1
t1:
Inner.m4t1()=0
t2:
Inner.m4t2()=4
t2:
Inner.m4t2()=3
t2:
Inner.m4t2()=2
t2:
Inner.m4t2()=1
t2:
Inner.m4t2()=0
第二篇:
synchronized关键字,它包括两种用法:
synchronized方法和synchronized块。
1.synchronized方法:
通过在方法声明中加入synchronized关键字来声明synchronized方法。
如:
publicsynchronizedvoidaccessVal(intnewVal);
synchronized方法控制对类成员变量的访问:
每个类实例对应一把锁,每个synchronized方法都必须获得调用该方法的类实例的锁方能
执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行
状态。
这种机制确保了同一时刻对于每一个类实例,其所有声明为synchronized的成员函数中至多只有一个处于可执行状态(因为至多只有
一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为synchronized)
。
在Java中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为synchronized,以控制其对类的静态成
员变量的访问。
synchronized方法的缺陷:
若将一个大的方法声明为synchronized将会大大影响效率,典型地,若将线程类的方法run()声明为
synchronized,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何synchronized方法的调用都永远不会成功。
当然我们可
以通过将访问类成员变量的代码放到专门的方法中,将其声明为synchronized,并在主方法中调用来解决这一问题,但是Java为我们提供
了更好的解决办法,那就是synchronized块。
2.synchronized块:
通过synchronized关键字来声明synchronized块。
语法如下:
synchronized(syncObject){
//允许访问控制的代码
}
synchronized块是这样一个代码块,其中的代码必须获得对象syncObject(如前所述,可以是类实例或类)的锁方能执行,具体机
制同前所述。
由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。
对synchronized(this)的一些理解
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。
另一个线
程必须等待当前线程执行完这个代码块以后才能执行该代码块。
二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized
(this)同步代码块。
三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)
同步代码块的访问将被阻塞。
四、第三个例子同样适用其它同步代码块。
也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个
object的对象锁。
结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
五、以上规则对其它对象锁同样适用
java中synchronized用法
打个比方:
一个object就像一个大房子,大门永远打开。
房子里有很多房间(也就是方法)。
这些房间有上锁的(synchronized方法),和不上锁之分(普通方法)。
房门口放着一把钥匙(key),这把钥匙可以打开所有上锁的房间。
另外我把所有想调用该对象方法的线程比喻成想进入这房子某个房间的人。
所有的东西就这么多了,下面我们看看这些东西之间如何作用的。
在此我们先来明确一下我们的前提条件。
该对象至少有一个synchronized方法,否则这个key还有啥意义。
当然也就不会有我们的这个主题了。
一个人想进入某间上了锁的房间,他来到房子门口,看见钥匙在那儿(说明暂时还没有其他人要使用上锁的房间)。
于是他走上去拿到了钥匙
,并且按