来源于《Java多线程编程核心技术》
一、join() 作用
在很多情况,主线程创建并启动子线程,如果子线程中需要进行大量的耗时计算,主线程往往早于子线程结束。这时,如果主线程想等待子线程执行结束之后再结束,比如子线程处理一个数据,主线程要取得这个数据,就要用待jion() 方法。
方法join()的作用是等待线程对象的销毁
二、区别
sleep(long)方法在睡眠时不释放对象锁
join(long)方法在等待的过程中释放对象锁
三、实例
创建join_sleep_1项目
类ThreadA.java代码如下
1 package extthread; 2 3 public class ThreadA extends Thread { 4 5 private ThreadB b; 6 7 public ThreadA(ThreadB b) { 8 super(); 9 this.b = b; 10 } 11 12 @Override 13 public void run() { 14 try { 15 synchronized (b) { 16 b.start(); 17 Thread.sleep(6000); 18 } 19 } catch (InterruptedException e) { 20 e.printStackTrace(); 21 } 22 } 23 }
类ThreadB.java代码如下
1 package extthread; 2 3 public class ThreadB extends Thread { 4 5 @Override 6 public void run() { 7 try { 8 System.out.println(" b run begin timer=" 9 + System.currentTimeMillis()); 10 Thread.sleep(5000); 11 System.out.println(" b run end timer=" 12 + System.currentTimeMillis()); 13 } catch (InterruptedException e) { 14 e.printStackTrace(); 15 } 16 } 17 18 synchronized public void bService() { 19 System.out.println("��ӡ��bService timer=" + System.currentTimeMillis()); 20 } 21 22 }
类ThreadC.java代码如
1 package extthread; 2 3 public class ThreadC extends Thread { 4 5 private ThreadB threadB; 6 7 public ThreadC(ThreadB threadB) { 8 super(); 9 this.threadB = threadB; 10 } 11 12 @Override 13 public void run() { 14 threadB.bService(); 15 } 16 }
Run.java 代码
1 package test.run; 2 3 import extthread.ThreadA; 4 import extthread.ThreadB; 5 import extthread.ThreadC; 6 7 public class Run { 8 public static void main(String[] args) { 9 10 try { 11 ThreadB b = new ThreadB(); 12 13 ThreadA a = new ThreadA(b); 14 a.start(); 15 16 Thread.sleep(1000); 17 18 ThreadC c = new ThreadC(b); 19 c.start(); 20 } catch (InterruptedException e) { 21 e.printStackTrace(); 22 } 23 } 24 }
结果
由于线程ThreadA使用Thread.sleep(long)方法一直持有ThreadB对象的锁,时间达到6秒,所以线程C只有在ThreadA时间到达6秒后释放ThreadB的锁时,才可以调用ThreadB中的同步方法Synchronized public void bService()
上面实验证明Thread.sleep(long)不释放锁
下面实验修改ThreadA.java
1 package extthread; 2 3 public class ThreadA extends Thread { 4 5 private ThreadB b; 6 7 public ThreadA(ThreadB b) { 8 super(); 9 this.b = b; 10 } 11 12 @Override 13 public void run() { 14 try { 15 synchronized (b) { 16 b.start(); 17 b.join(); 18 for (int i = 0; i < Integer.MAX_VALUE; i++) { 19 String newString = new String(); 20 Math.random(); 21 } 22 } 23 } catch (InterruptedException e) { 24 e.printStackTrace(); 25 } 26 } 27 }
结果如下
由于线程ThreadA释放了ThreadB的锁,所以线程ThreadC可以调用ThreadB中的同步方法synchronized public void bService()
实验证明join(long)方法具有释放锁的特点