理解了好長(zhǎng)時(shí)間哇。。。
1 public final synchronized void join(long millis) 2 throws InterruptedException { 3 long base = System.currentTimeMillis(); 4 long now = 0; 5 6 if (millis < 0) { 7 throw new IllegalArgumentException("timeout value is negative"); 8 } 9 10 if (millis == 0) {11 while (isAlive()) {12 wait(0);13 }14 } else {15 while (isAlive()) {16 long delay = millis - now;17 if (delay <= 0) {18 break;19 }20 wait(delay);21 now = System.currentTimeMillis() - base;22 }23 }24 }
其實(shí)從源碼來說,光想做到阻塞,那個(gè)while(isAlive())就做到了。 那么這兒也先當(dāng)問題,為什么還要wait呢?如果只為了阻塞的話。
可能吧: 其實(shí)作為多線程的環(huán)境,作為設(shè)計(jì)者,第一時(shí)間一定會(huì)想到wait,因?yàn)檫@樣肯定沒問題。
我把調(diào)用 t.join的過程都弄到main函數(shù)里了,這樣清楚點(diǎn)。
public static void main(String[] args) { ThreadTest t = new ThreadTest(); t.start(); synchronized (t){ while (t.isAlive()){ try { t.wait(0); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println(Thread.currentThread().getName()); System.out.println(i); }
因?yàn)閖oin方法是個(gè)synchroniez方法,所以想要在任何線程里調(diào)用,先獲取到t的對(duì)象再說,即上面那樣
然后t.wait(0) 很容易誤解成把線程t給wait了,其實(shí)不然。
對(duì)于main線程來說,線程t只是個(gè)同步對(duì)象。這一切的操作,都在main線程中。所以是把main線程,放到了同步對(duì)象t的等待隊(duì)列中。所以是main線程waiting狀態(tài)。
Thread.exit()方法,調(diào)用了 group.threadTerminated方法,這個(gè)細(xì)看看吧,主要是remove(t); if (nthreads == 0) {notifyAll();}
其實(shí)這幾種方式的本質(zhì)是:synchronized可以作用于不同的地方,而這三種東西都可以作為同步對(duì)象(鎖)。
聯(lián)系客服