Java多线程学习:Join()

方法join的作用是使所属的线程对象x正常执行run()方法中的任务,而使当前线程Z进行无限期的阻塞,等待线程X销毁后再继续执行线程Z后面的代码。一般用于子线程先执行完毕再继续执行主线程的情况。

但是join方法后面的代码会不会提前执行呢?看下面的代码

 1 public class ThreadA extends Thread {
 2 
 3     private ThreadB threadB;
 4 
 5     public ThreadA(ThreadB threadB) {
 6         super();
 7         this.threadB = threadB;
 8     }
 9 
10     @Override
11     public void run() {
12         synchronized (threadB) {
13             System.out.println("begin A ThreadName=" + Thread.currentThread().getName());
14             try {
15                 Thread.sleep(5000);
16             } catch (InterruptedException e) {
17                 e.printStackTrace();
18             }
19             System.out.println("end A ThreadName=" + Thread.currentThread().getName());
20         }
21     }
22 
23 
24 }
View Code
 1 public class ThreadB extends Thread{
 2     @Override
 3     public void run() {
 4         System.out.println("begin B ThreadName=" + Thread.currentThread().getName());
 5         try {
 6             Thread.sleep(5000);
 7         } catch (InterruptedException e) {
 8             e.printStackTrace();
 9         }
10         System.out.println("end B ThreadName=" + Thread.currentThread().getName());
11     }
12 }
View Code
 1 public class Run {
 2     public static void main(String[] args) throws InterruptedException {
 3         ThreadB threadB = new ThreadB();
 4         ThreadA threadA = new ThreadA(threadB);
 5         threadA.start();
 6         threadB.start();
 7         threadB.join(2000);
 8         System.out.println("main thread");
 9 
10     }
11 }
View Code

运行几次后会发现,大部分时候结果是

但也会出现如下结果

join方法后面的代码提前执行了,这是怎么一回事呢?我们修改Run.java,将join方法注释掉,再次运行,发现结果如下

通过多次运行Run.java文件后,可以发现一个规侓:main end往往都是第一个打印的。所以可以完全确定地得出一个结论:方法join(2000)大部分是先运行的,也就是先抢到ThreadB的锁,然后快速进行释放。

代码运行步骤如下:

1)b.join(2000)方法先抢到B锁,然后将B锁进行释放;

2)ThreadA抢到锁,打印 ThreadA begin 并且 sleep(5000);

3)ThreadA 打印 ThreadA end,并释放锁;

4)这时join(2000)和ThreadB争抢锁,而join(2000)再次抢到锁,发现时间已过,释放锁;

5)ThreadB 抢到锁打印 ThreadB begin,main线程也异步打印main end;

6)5秒之后再打印ThreadB end。

这样就会出现join方法后面的代码提前执行的情况。

猜你喜欢

转载自www.cnblogs.com/le-le/p/12074712.html