关于Thread.join()的理解

先看代码:

public static void main(String[] args) {
    	Thread son = new Thread(() -> {
    		Thread.sleep(5000);
			System.out.println("im thread son!!!");
    	});
    	son.start();
		son.join();
    	System.out.println("im thread main!!!");
}
运行结果;
im thread son!!!
im thread main!!!

join的JDK源码:

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;
            }
        }
    }

注意方法上的synchronized字段(锁的资源是this对象)

调用 thread.join() 相当于join(long millis) 方法中传入的参数为0;

所以源码实际上生效的代码段为:

 while (isAlive()) {
                wait(0);
            }
        }     

如果线程是alive状态的就死循环调用 wait(0)方法,所以调用 thread.join() 方法的地方,相当于同时调用了thread.wait(),

因此调用thread.join()方法的线程会被阻塞,保证子线程执行完再执行主线程。

把这段生效代码挪到主线程中,替代join方法:

public static void main(String[] args) {
    	Thread son = new Thread(() -> {
    		Thread.sleep(5000);
			System.out.println("im thread son!!!");
    	});
    	son.start();
    	// son.join(); 相当于下面的代码
    	
    	synchronized(son) {
    		while(son.isAlive()) {
    			//阻塞了主线程。 son既是线程,又是竞争的锁对象
    			son.wait(0);
    		}
    	}
    	
    	System.out.println("im thread main!!!");
    }
运行结果仍然是;
im thread son!!!
im thread main!!!

两段代码的代码含义完全一样,第二段代码用join中的源码替代了join但更 易于理解join的原理。

在thread执行完成的时候会调用notify() 方法,调用join方法的地方就会继续执行。

你可能感兴趣的:(JAVA并发)