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

  • 相关阅读:
    Java Comparator和Comparabler的区别
    正则表达式全部符号解释
    Java使用reids,以及redis与shiro集成
    jQuery的select相关操作
    javascrit原生实现jquery的append()函数
    spring拦截器 实现应用之性能监控
    Gitlab完美安装【CentOS6.5安装gitlab-6.9.2】
    关于datepicker只显示年、月、日的设置
    spring aop 环绕通知around和其他通知的区别
    springMVC和spring各自扫描自己的注解不要相互混淆
  • 原文地址:https://www.cnblogs.com/qf123/p/9681313.html
Copyright © 2020-2023  润新知