join(long)方法和sleep(long)方法的比较

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后释放了锁

posted @ 2018-09-20 15:46  *青锋*  阅读(546)  评论(0编辑  收藏  举报