java join()方法
阿新 • • 發佈:2019-01-02
join方法
合併執行緒?怎末實現?
public final synchronized void join()
public final synchronized void join(long millis)
public static void main(String[] args) {
// run類實現了runnable介面
Run r = new Run();
Thread t1 = new Thread(r, "t1");
try {
t1.start();
// t1.join(); // 相當於t1.join(0); main執行緒等到t1執行完再往下執行
// main執行緒暫停直到200ms或t1執行結束
t1.join(200);
System.out.println("t1 end");
} catch(Exception e) {
e.printStackTrace();
}
System.out.println("main end");
}
class Run2 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(200);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
它就是提供了這麼一個功能,具體實現看不懂,有native方法
// 其中的wait()方法為native方法,正是Object類的wait()方法
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
現在又有一個疑問了,如果是普通物件呼叫wait()方法,那麼訪問該物件的執行緒wait,如果是執行緒物件呼叫wait()方法,那麼誰wait()呢?main執行緒?
糊塗了,糊塗了。wait方法和物件無關,和訪問物件的執行緒有關,訪問Thread.wait()方法的是main執行緒,所以wait的是main執行緒。
既然這樣就好理解了
join方法阻塞呼叫方法的執行緒,這樣就造成了執行緒合併的假象。實質上就是一個執行緒的wait。
那麼,main執行緒wait了,怎末沒有notify呢?
看了文件才知道
* <p> This implementation uses a loop of {@code this.wait} calls
* conditioned on {@code this.isAlive}. As a thread terminates the
* {@code this.notifyAll} method is invoked. It is recommended that
* applications not use {@code wait}, {@code notify}, or
* {@code notifyAll} on {@code Thread} instances.
join方法呼叫結束時,notifyAll方法自動被呼叫。
這樣,main執行緒又能繼續執行了。