join(long)方法的源代码

     public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0; if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
} if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}

sleep(long)方法的源代码

public static native void sleep(long millis) throws InterruptedException;

从源代码中可以发现,join(long)方法内部使用wait(long)实现,所以join(long)方法执行后会释放锁,所以其他线程就可以调用此线程中的同步方法

验证sleep(long)方法会不会释放锁

--------------------------------------------------------线程类--------------------------------------------------------

 package com.qf.test04.thread;

 /**
* @author qf
* @create 2018-09-20 15:22
*/
public class ThreadA extends Thread {
private ThreadB threadB; public ThreadA(ThreadB threadB) {
this.threadB = threadB;
} @Override
public void run() {
try {
synchronized (threadB){
threadB.start();
Thread.sleep(6000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
 package com.qf.test04.thread;

 /**
* @author qf
* @create 2018-09-20 15:22
*/
public class ThreadB extends Thread {
@Override
public void run() {
try {
System.out.println("b run begin time = "+System.currentTimeMillis());
Thread.sleep(5000);
System.out.println("b run --end time = "+System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
} public synchronized void bService(){
System.out.println("bService time = "+System.currentTimeMillis());
}
}
 package com.qf.test04.thread;

 /**
* @author qf
* @create 2018-09-20 15:22
*/
public class ThreadC extends Thread {
private ThreadB threadB; public ThreadC(ThreadB threadB) {
this.threadB = threadB;
} @Override
public void run() {
threadB.bService();
}
}

--------------------------------------------------------测试类--------------------------------------------------------

 package com.qf.test04;

 import com.qf.test04.thread.ThreadA;
import com.qf.test04.thread.ThreadB;
import com.qf.test04.thread.ThreadC; /**
* @author qf
* @create 2018-09-20 15:22
*/
public class Run {
public static void main(String[] args) {
try {
ThreadB b = new ThreadB();
ThreadA a = new ThreadA(b);
a.start();
Thread.sleep(1000);
ThreadC c = new ThreadC(b);
c.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

-------------------------------------------------------打印输出------------------------------------------------------

b run begin time = 1537429005098
b run --end time = 1537429010098
bService time = 1537429011098

结果显示只有a线程执行完毕(sleep了6000ms),c线程才能执行,所以sleep方法并没有释放锁

验证join(long)方法释放锁

修改ThreadA.java中的代码

-----------------------------------------------------ThreadA.java----------------------------------------------------

 package com.qf.test04.thread;

 /**
* @author qf
* @create 2018-09-20 15:22
*/
public class ThreadA extends Thread {
private ThreadB threadB; public ThreadA(ThreadB threadB) {
this.threadB = threadB;
} @Override
public void run() {
try {
synchronized (threadB){
threadB.start();
//Thread.sleep(6000);
threadB.join();
for (int i = 0; i < Integer.MAX_VALUE ; i++) {
//用于耗时
String newString = new String();
Math.random();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

-------------------------------------------------------打印输出------------------------------------------------------

b run begin time = 1537429346791
bService time = 1537429347790
b run --end time = 1537429351793

bService在1000后执行打印,说明c线程获得了threadB的锁,所以a线程在join后释放了锁

join(long)方法和sleep(long)方法的比较的更多相关文章

  1. $(document).ready()即$()方法和window.onload方法的比较

    以浏览器装载文档为例,我们都知道在页面完毕后,浏览器会通过JavaScript为DOM元素添加事件.在常规的JavaScript代码中,通常使用window.onload方法,而在jQuery中,使用 ...

  2. Server.Transfer方法,Server.Execute方法和Response.Redirect方法有什么异同

    (1)Server.Transfer方法: Server.Transfer("m2.aspx");//页面转向(服务器上执行). 服务器停止解析本页,保存此页转向前的数据后,再使页 ...

  3. java——多线程——单例模式的static方法和非static方法是否是线程安全的?

    单例模式的static方法和非static方法是否是线程安全的? 答案是:单例模式的static方法和非static方法是否是线程安全的,与单例模式无关.也就说,如果static方法或者非static ...

  4. synchronized 修饰在 static方法和非static方法的区别

    Java中synchronized用在静态方法和非静态方法上面的区别 在Java中,synchronized是用来表示同步的,我们可以synchronized来修饰一个方法.也可以synchroniz ...

  5. $(document).ready()方法和window.onload()方法

    $(document).ready()方法和window.onload()方法 $(document).ready()方法是JQuery中的方法,他在DOM完全就需时就可以被调用,不必等待这些元素关联 ...

  6. Html.Partial方法和Html.RenderPartial方法

    分布视图 PartialView 一般是功能相对独立的,类似用户控件的视图代码片段,可以被多个视图引用,引用方式如下. 1,Html.Partial方法和Html.RenderPartial方法 静态 ...

  7. tornado的IOLoop.instance()方法和IOLoop.current()方法区别

    在使用tornado时,经常有人疑惑IOLoop.instance()方法和IOLoop.current()方法的区别是什么. IOLoop.instance() 返回一个全局 IOLoop实例. 大 ...

  8. 【转载】C#中double.TryParse方法和double.Parse方法的异同之处

    在C#编程过程中,double.TryParse方法和double.Parse方法都可以将字符串string转换为double类型,但两者还是有区别,最重要的区别在于double.TryParse方法 ...

  9. 【转载】 C#中decimal.TryParse方法和decimal.Parse方法的异同之处

    在C#编程过程中,decimal.TryParse方法和decimal.Parse方法都可以将字符串string转换为decimal类型,但两者还是有区别,最重要的区别在于decimal.TryPar ...

随机推荐

  1. Php 十六进制短浮点数转十进制,带符号位

    /** * 十六进制浮点型转为十进制 * @param String $strHex 十六进制浮点数 * @return 十进制 */ public static function hexToDecF ...

  2. Select.snippet

    <?xml version="1.0" encoding="utf-8"?> <CodeSnippets xmlns="http:/ ...

  3. C#获取文件夹/文件的大小以及占用空间 转摘自:http://www.cnblogs.com/chenpeng-dota/articles/2176470.html

    C#获取文件夹/文件的大小以及占用空间 今天,头给了个任务:写个方法,我会给你个路径,计算这个路径所占用的磁盘空间 . 然后,找了很多资料.但大部分都是获取文件夹/文件的大小的.对于占用空间的没有成品 ...

  4. [转]Linux Shell编程入门

    转自:http://www.cnblogs.com/suyang/archive/2008/05/18/1201990.html 从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的 ...

  5. spring3.0+struts2+ibatis整合

    User.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMap PUBLI ...

  6. hibernate 参数一览

    实现包含了Hibernate与数据库的基本连接信息的配置方式有两种方式: 第一种是使用hibernate.properties文件作为配置文件. 第二种是使用hibernate.cfg.xml文件作为 ...

  7. 力扣——single number 2(只出现一次的数字 2) python实现

    题目描述: 中文: 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? ...

  8. jq 常识复记01-- 数组操作

    删除数组指定的某个元素 js删除数组中某一项或几项的几种方法 https://www.jb51.net/article/154737.htm 首先可以给JS的数组对象定义一个函数,用于查找指定的元素在 ...

  9. Python3.5-20190518-廖老师-自我笔记-面向对象

    面向对象编程,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 把老师分为一类,把学生分为一类.具体到某一个学生就是  这类中的一个具体对象,对象的 ...

  10. jenkins参数化配置,pom.xml配置

    1.要实现Jenkins参数化构建,要先在代码里写好能接收该参数value的配置,在pom.xml文件里加配置,如下: 1)<properties></properties>里 ...