作用:join()方法的作用是等待線程對象銷毀。
join()方法具有能使線程排隊運行的作用,有點類似於同步的效果。
join與synchronize的區別:
join在內部使用wait()方法進行等待,底層用wait()來實現。
synchronize關鍵字是以“對象監視器”為原理做同步操作。
join()除了無參方法之外,還重載了join(毫秒)的方法,此方法與sleep(毫秒)的區別是:
join()操作底層用wait()來實現,可以釋放鎖。
sleep()不會釋放鎖。
join()釋放鎖的demo:
線程類A:
package com.wang.myjoin;
publicclassThreadAextendsThread{
privateThreadB threadB;
publicThreadA(ThreadB threadB){
this.threadB = threadB;
}
@Override
publicvoid run(){
synchronized(threadB){
threadB.start();
try{
threadB.join();
}catch(InterruptedException e1){
e1.printStackTrace();
}
for(int i =0;i<10000;i++){
System.out.println("b do sth....");
}
}
}
}
線程類B:
package com.wang.myjoin;
publicclassThreadBextendsThread{
@Override
publicvoid run(){
System.out.println("B thread is run.");
try{
Thread.sleep(2000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("B thread is over.");
}
publicsynchronizedvoid myService(){
for(int i =0;i<100;i++){
System.out.println("myService do sth."+ i);
}
}
}
線程類C:
package com.wang.myjoin;
publicclassThreadCextendsThread{
privateThreadB threadB;
publicThreadC(ThreadB threadB){
this.threadB = threadB;
}
@Override
publicvoid run(){
threadB.myService();
}
}
測試類:
package com.wang.myjoin;
publicclassJoinTest{
publicstaticvoid main(String[] args){
ThreadB threadB =newThreadB();
ThreadA threadA =newThreadA(threadB);
threadA.start();
ThreadC threadC =newThreadC(threadB);
threadC.start();
System.out.println("~~~我來測試一下~~~~");
}
}
輸出結果:
B thread is run.
~~~我來測試一下~~~~
myService do sth.0
myService do sth.1
myService do sth.2
.
.
.
myService do sth.99
B thread is over.
b do sth....
b do sth....
.
.
.
可見線程在join()之后是釋放鎖的,其他線程可以訪問同鎖的synchronize方法。
需要注意的問題:join()后的方法有可能會提前運行:(這個沒試出來)
我們同時執行以下三個操作:
①.thread1.start();
②.thread2.start();
③.sysout
哪個先運行是不確定的,不過①和②的操作是相同的鎖,所以是互斥的。