|
理解了好長時間哇。。。 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 }
Thread.join問題1:為什么能阻塞當前線程?其實從源碼來說,光想做到阻塞,那個while(isAlive())就做到了。 那么這兒也先當問題,為什么還要wait呢?如果只為了阻塞的話。 可能吧: 其實作為多線程的環(huán)境,作為設(shè)計者,第一時間一定會想到wait,因為這樣肯定沒問題。 問題2:為什么wait(0)運行的結(jié)果是main線程變成了waiting狀態(tài)?(其實很好理解,但是很容易誤解)我把調(diào)用 t.join的過程都弄到main函數(shù)里了,這樣清楚點。 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);
}
因為join方法是個synchroniez方法,所以想要在任何線程里調(diào)用,先獲取到t的對象再說,即上面那樣 然后t.wait(0) 很容易誤解成把線程t給wait了,其實不然。 對于main線程來說,線程t只是個同步對象。這一切的操作,都在main線程中。所以是把main線程,放到了同步對象t的等待隊列中。所以是main線程waiting狀態(tài)。 問題3:什么時候把waiting的線程notify了?Thread.exit()方法,調(diào)用了 group.threadTerminated方法,這個細看看吧,主要是remove(t); if (nthreads == 0) {notifyAll();} synchronized幾種不同的加鎖位置,需要獲取的鎖(監(jiān)視)對象
其實這幾種方式的本質(zhì)是:synchronized可以作用于不同的地方,而這三種東西都可以作為同步對象(鎖)。 |
|
|