来源于《Java多线程编程核心技术》

一、join() 作用

在很多情况,主线程创建并启动子线程,如果子线程中需要进行大量的耗时计算,主线程往往早于子线程结束。这时,如果主线程想等待子线程执行结束之后再结束,比如子线程处理一个数据,主线程要取得这个数据,就要用待jion() 方法。

方法join()的作用是等待线程对象的销毁

二、区别

  sleep(long)方法在睡眠时不释放对象锁

  join(long)方法在等待的过程中释放对象锁

三、实例

  创建join_sleep_1项目

  

  类ThreadA.java代码如下

 package extthread;

 public class ThreadA extends Thread {

     private ThreadB b;

     public ThreadA(ThreadB b) {
super();
this.b = b;
} @Override
public void run() {
try {
synchronized (b) {
b.start();
Thread.sleep(6000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

类ThreadB.java代码如下

 package extthread;

 public class ThreadB extends Thread {

     @Override
public void run() {
try {
System.out.println(" b run begin timer="
+ System.currentTimeMillis());
Thread.sleep(5000);
System.out.println(" b run end timer="
+ System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
} synchronized public void bService() {
System.out.println("��ӡ��bService timer=" + System.currentTimeMillis());
} }

类ThreadC.java代码如

 package extthread;

 public class ThreadC extends Thread {

     private ThreadB threadB;

     public ThreadC(ThreadB threadB) {
super();
this.threadB = threadB;
} @Override
public void run() {
threadB.bService();
}
}

Run.java 代码

 package test.run;

 import extthread.ThreadA;
import extthread.ThreadB;
import extthread.ThreadC; 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();
}
}
}

结果

由于线程ThreadA使用Thread.sleep(long)方法一直持有ThreadB对象的锁,时间达到6秒,所以线程C只有在ThreadA时间到达6秒后释放ThreadB的锁时,才可以调用ThreadB中的同步方法Synchronized public void bService()

上面实验证明Thread.sleep(long)不释放锁


下面实验修改ThreadA.java

 package extthread;

 public class ThreadA extends Thread {

     private ThreadB b;

     public ThreadA(ThreadB b) {
super();
this.b = b;
} @Override
public void run() {
try {
synchronized (b) {
b.start();
b.join();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
String newString = new String();
Math.random();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

结果如下

由于线程ThreadA释放了ThreadB的锁,所以线程ThreadC可以调用ThreadB中的同步方法synchronized public void bService()

实验证明join(long)方法具有释放锁的特点

join() 和 sleep() 区别的更多相关文章

  1. join 和 union 区别

    JOIN和UNION区别 join 是两张表做交连后里面条件相同的部分记录产生一个记录集,union是产生的两个记录集(字段要一样的)并在一起,成为一个新的记录集 .JOIN用于按照ON条件联接两个表 ...

  2. sql的left join 、right join 、inner join之间的区别

    sql中left join .right join .inner join之间的区别 left join (左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 : right join (右 ...

  3. inner join 与 left join 之间的区别

    关于inner join 与 left join 之间的区别,以前以为自己搞懂了,今天从前端取参数的时候发现不是预想中的结果,才知道问题出在inner join 上了. 需求是从数据库查数据,在前端以 ...

  4. Oracle中 (+)与left join 的用法区别

    Oracle中 (+)与left join 的用法区别 原创 2017年01月11日 13:33:42 6648 select * from a,b where a.id=b.id(+); (+)写在 ...

  5. inner join(inner可省) 与 left join 之间的区别

    关于inner join 与 left join 之间的区别,以前以为自己搞懂了,今天从前端取参数的时候发现不是预想中的结果,才知道问题出在inner join 上了. 需求是从数据库查数据,在前端以 ...

  6. 1.JOIN和UNION区别

    1.JOIN和UNION区别join 是两张表做交连后里面条件相同的部分记录产生一个记录集,union是产生的两个记录集(字段要一样的)并在一起,成为一个新的记录集 . JOIN用于按照ON条件联接两 ...

  7. left join 、right join 和inner join之间的区别

    SQL的left join .right join 和inner join之间的区别 left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录  right join(右联接) ...

  8. Java线程中yield与join方法的区别

    长期以来,多线程问题颇为受到面试官的青睐.虽然我个人认为我们当中很少有人能真正获得机会开发复杂的多线程应用(在过去的七年中,我得到了一个机会),但是理解多线程对增加你的信心很有用.之前,我讨论了一个w ...

  9. left join,right join,inner join,full join之间的区别

    参考 https://www.cnblogs.com/assasion/p/7768931.html https://blog.csdn.net/rongbo_j/article/details/46 ...

  10. join和+的区别

    连接字符串的时候可以用join也可以用+,但这两者有没有区别呢? 我们先来看一下用join和+连接字符串的例子 str1 = " ".join(["hello" ...

随机推荐

  1. Dapper相关了解

    公司新项目用的是Dapper,做的时候没有具体看dapper的具体用法,现在回来回顾总结一下. 1-总体介绍dapper 我们都知道ORM全称叫做Object Relationship Mapper, ...

  2. access + vb + asp 遇到一些问题的总结

    Data Base access + vb + asp  遇到一些问题的总结 1.asp中sql语句: select * from users whre name=’张三‘ and addTime=# ...

  3. [SinGuLaRiTy] 2017-04-08 综合性测试

    [SinGuLaRiTy-1016] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 对于所有的题目:Time Limit:1s  |  Me ...

  4. 【OD深入学习】Java多线程面试题

    一.参考文章 1. Java线程面试题 Top 50 2. Java面试——多线程面试题 3. JAVA多线程和并发基础面试问答 4. 15个顶级Java多线程面试题及回答 二.逐个解答 三.一语中的 ...

  5. AngularJS(三)——指令实战及自定义指令

    前言 上篇介绍了一些指令的应用,本篇介绍一些常用的用法格式. 内容 指令实战 下面通过输入一个名字实现实时更新文本内容. 需要的指令有: ng-app.ng-model.ng-bind.n-init ...

  6. C++基础学习9:构造函数和析构函数

    1.  构造函数用来对类对象进行初始化,它完成对内存空间的申请.赋初值等工作.  2.  析构函数主要是用来做清理工作的. 补充:函数名或变量名前面有"::"但是没有类名,说明这是 ...

  7. 关于thinkphp5中数据库分组查询group

    在使用tp5的group进行分组查询总是报错,以主键进行分组是不报错,但没有任何意义 与聚合函数一起使用的不会报错,如官方文档给出的代码 Db::table('think_user') ->fi ...

  8. Mybatis学习笔记(八) —— Mybatis整合spring

    一.整合思路 1.SqlSessionFactory对象应该放到spring容器中作为单例存在. 2.传统dao的开发方式中,应该从spring容器中获得sqlsession对象. 3.Mapper代 ...

  9. logrotate 日志管理

    查看logrotate 是否已安装 因为linux安装软件的方式比较多,所以没有一个通用的办法能查到某些软件是否安装了.总结起来就是这样几类: 1.rpm包安装的,可以用rpm -qa看到,如果要查找 ...

  10. day17 isinstance type issubclass 反射

    1. issubclass,type,isinstance 1.issubclass 判断xxx是否yyy的子类 例: class Foo: pass class Bar(Foo): pass cla ...