join(long)方法的源代码
1 public final synchronized void join(long millis) 2 throws InterruptedException { 3 long base = System.currentTimeMillis(); 4 long now = 0; 5 6 if (millis < 0) { 7 throw new IllegalArgumentException("timeout value is negative"); 8 } 9 10 if (millis == 0) { 11 while (isAlive()) { 12 wait(0); 13 } 14 } else { 15 while (isAlive()) { 16 long delay = millis - now; 17 if (delay <= 0) { 18 break; 19 } 20 wait(delay); 21 now = System.currentTimeMillis() - base; 22 } 23 } 24 }
sleep(long)方法的源代码
1 public static native void sleep(long millis) throws InterruptedException;
从源代码中可以发现,join(long)方法内部使用wait(long)实现,所以join(long)方法执行后会释放锁,所以其他线程就可以调用此线程中的同步方法
验证sleep(long)方法会不会释放锁
--------------------------------------------------------线程类--------------------------------------------------------
1 package com.qf.test04.thread; 2 3 /** 4 * @author qf 5 * @create 2018-09-20 15:22 6 */ 7 public class ThreadA extends Thread { 8 private ThreadB threadB; 9 10 public ThreadA(ThreadB threadB) { 11 this.threadB = threadB; 12 } 13 14 @Override 15 public void run() { 16 try { 17 synchronized (threadB){ 18 threadB.start(); 19 Thread.sleep(6000); 20 } 21 } catch (InterruptedException e) { 22 e.printStackTrace(); 23 } 24 } 25 }
1 package com.qf.test04.thread; 2 3 /** 4 * @author qf 5 * @create 2018-09-20 15:22 6 */ 7 public class ThreadB extends Thread { 8 @Override 9 public void run() { 10 try { 11 System.out.println("b run begin time = "+System.currentTimeMillis()); 12 Thread.sleep(5000); 13 System.out.println("b run --end time = "+System.currentTimeMillis()); 14 } catch (InterruptedException e) { 15 e.printStackTrace(); 16 } 17 } 18 19 public synchronized void bService(){ 20 System.out.println("bService time = "+System.currentTimeMillis()); 21 } 22 }
1 package com.qf.test04.thread; 2 3 /** 4 * @author qf 5 * @create 2018-09-20 15:22 6 */ 7 public class ThreadC extends Thread { 8 private ThreadB threadB; 9 10 public ThreadC(ThreadB threadB) { 11 this.threadB = threadB; 12 } 13 14 @Override 15 public void run() { 16 threadB.bService(); 17 } 18 }
--------------------------------------------------------测试类--------------------------------------------------------
1 package com.qf.test04; 2 3 import com.qf.test04.thread.ThreadA; 4 import com.qf.test04.thread.ThreadB; 5 import com.qf.test04.thread.ThreadC; 6 7 /** 8 * @author qf 9 * @create 2018-09-20 15:22 10 */ 11 public class Run { 12 public static void main(String[] args) { 13 try { 14 ThreadB b = new ThreadB(); 15 ThreadA a = new ThreadA(b); 16 a.start(); 17 Thread.sleep(1000); 18 ThreadC c = new ThreadC(b); 19 c.start(); 20 } catch (InterruptedException e) { 21 e.printStackTrace(); 22 } 23 } 24 }
-------------------------------------------------------打印输出------------------------------------------------------
b run begin time = 1537429005098 b run --end time = 1537429010098 bService time = 1537429011098
结果显示只有a线程执行完毕(sleep了6000ms),c线程才能执行,所以sleep方法并没有释放锁
验证join(long)方法释放锁
修改ThreadA.java中的代码
-----------------------------------------------------ThreadA.java----------------------------------------------------
1 package com.qf.test04.thread; 2 3 /** 4 * @author qf 5 * @create 2018-09-20 15:22 6 */ 7 public class ThreadA extends Thread { 8 private ThreadB threadB; 9 10 public ThreadA(ThreadB threadB) { 11 this.threadB = threadB; 12 } 13 14 @Override 15 public void run() { 16 try { 17 synchronized (threadB){ 18 threadB.start(); 19 //Thread.sleep(6000); 20 threadB.join(); 21 for (int i = 0; i < Integer.MAX_VALUE ; i++) { 22 //用于耗时 23 String newString = new String(); 24 Math.random(); 25 } 26 } 27 } catch (InterruptedException e) { 28 e.printStackTrace(); 29 } 30 } 31 }
-------------------------------------------------------打印输出------------------------------------------------------
b run begin time = 1537429346791 bService time = 1537429347790 b run --end time = 1537429351793
bService在1000后执行打印,说明c线程获得了threadB的锁,所以a线程在join后释放了锁