这段代码是用于验证join方法的使用, 一个线程通过join方法等待另一个线程的执行结束, 按照我的理解, 应该是a和b有序输出, 且主线程一定在b输出之后输出. 但是实际运行结果并不是这样的. 实际的输出如下:
书上讲不光会出现这种情况, 还有可能出现:
threadA sleep start , end
threadB sleep start
main end
threadB sleep end
对于这两种情况该怎么解释呢?
代码如下:
public class Main
{
public static void main(String[] args)throws Exception
{
try {
ThreadB b = new ThreadB() ;
ThreadA a = new ThreadA(b) ;
a.start();
b.start();
b.join(2000) ;//似乎问题的关键就是这一行, 但是我无法解释为什么
System.out.println("main end");
Thread.sleep(1);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
class ThreadA extends Thread
{
private ThreadB b ;
public ThreadA(ThreadB b) {
this.b = b;
}
@Override
public void run() {
try {
synchronized (b)
{
System.out.println("threadA sleep start ....");
this.sleep(5000) ;
System.out.println("threadA sleep end....");
}
}
catch (InterruptedException e)
{
e.printStackTrace() ;
}
}
}
class ThreadB extends Thread
{
@Override
public synchronized void run() {
try {
System.out.println("threadB sleep start....");
this.sleep(5000);
System.out.println("threadB sleep end....");
}
catch (InterruptedException e)
{
e.printStackTrace() ;
}
}
}
关键在于
和
这两块代码是互斥的,有一处拿到了锁,另一处就会阻塞在那里。原因是当synchronized的参数是一个对象,那么该对象的synchronized方法都会被阻塞,而join恰恰是synchronized的
这两块代码谁先执行,结合楼主自己说的join的等待时间,会产生各种结果