java 多執行緒程式設計之join()的用法
程式1:
public class ThreadTest implements Runnable {
public static int a = 0;
public synchronized void inc() {
a++;
}
public void run() {
for (int i = 0; i < 5; i++) {
inc();
}
}
public static void main(String[] args) throws Exception {
Runnable r = new ThreadTest();
Thread t1 = new Thread(r);
t1.start();
System.out.println(a);
}
}
咋一看以為結果是:5 ,其實不然
程式2:在一基礎上新增點東西 System.out.println(a+",");
public class ThreadTest implements Runnable {
public static int a = 0;
public synchronized void inc() {
a++;
System.out.println(a+",");
}
public void run() {
for (int i = 0; i < 5; i++) {
inc();
}
}
public static void main(String[] args) throws Exception {
Runnable r = new ThreadTest();
Thread t1 = new Thread(r);
t1.start();
System.out.println(a);
}
}
結果:
0
1,2,3,4,5,
說明a已經被加了5次。但有兩個問題
1)為什麼main方法中的列印語句還是0呢?
2)為什麼main方法中的列印語句先執行了呢?
程式3
public class ThreadTest implements Runnable {
public static int a = 0;
public synchronized void inc() {
a++;
}
public void run() {
for (int i = 0; i < 5; i++) {
inc();
}
}
public static void main(String[] args) throws Exception {
Runnable r = new ThreadTest();
Thread t1 = new Thread(r);
t1.start();
for (int i=0; i<300; i++) {
System.out.print(i);
}
System.out.println();
System.out.println(a);
}
}
結果:
0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
5
此時的結果5正確了。說明執行緒在i迴圈100次後,全部都結束了。
之所以會產生1)和2)原因是:由於有兩個執行緒,我們不知道主執行緒執行到什麼時候開始執行子執行緒,這是由於雖然你呼叫start方法但是呼叫該方法只是準備執行緒並不是馬上啟動.所以,當程式執行的時候,很隨機地執行這兩個執行緒中的一個,也就很隨機地執行System.out.println(a); 這個語句了.於是,有可能子執行緒只執行了1次a=+1這個語句,也可能是2次或者其它多少次,還可能是0次,所以列印的結果是個隨機數
程式4:在程式1的基礎上新增 t1.join(); 達到與程式3同樣的效果
public class ThreadTest implements Runnable {
public static int a = 0;
public synchronized void inc() {
a++;
}
public void run() {
for (int i = 0; i < 5; i++) {
inc();
}
}
public static void main(String[] args) throws Exception {
Runnable r = new ThreadTest();
Thread t1 = new Thread(r);
t1.start();
t1.join();
System.out.println(a);
}
}
結果:5
總結:join方法的功能就是使非同步執行的執行緒變成同步執行。也就是說,當呼叫執行緒例項的start方法後,這個方法會立即返回,如果在呼叫start方法後後需要使用一個由這個執行緒計算得到的值,就必須使用join方法。如果不使用join方法,就不能保證當執行到start方法後面的某條語句時,這個執行緒一定會執行完。而使用join方法後,直到這個執行緒退出,程式才會往下執行。