java多线程16:join()的使用
讲解join()方法之前请确保对于即wait()/notify()/notifyAll()机制已熟练掌握。可以参考前面的笔记
join()方法的作用是等待线程销毁。join()方法反应的是一个很现实的问题,比如main线程的执行时间是1s,子线程的执行时间是10s,但是主线程依赖子线程执行完的结果,这时怎么办?可以像生产者/消费者模型一样,搞一个缓冲区,子线程执行完把数据放在缓冲区中,通知main线程,main线程去拿,这样就不会浪费main线程的时间了。另外一种方法,就是join()了。
join()方法之前的铺垫
上面的主线程想等待子线程,但是主线程先打印了,如果要实现主线程等待呢
用join()来解决
使用join成功的让主线程等待了,其实join内部还是使用的等待,所以join是放锁的
join()方法与异常
上面是ThreadB 调用a.join(),其实根据join的源码是当前B线程锁a线程对象,wait之后,B线程等待A线程notify,而要interrupt B线程就会出现异常,但是A线程还是继续,A线程是不受影响的
join(long)方法的使用
通过上面代码可以发现 join(long) 和 sleep(long)实现的效果是一样
join()方法的一个重点是要区分出和sleep()方法的区别。join(2000)也是可以的,表示调用join()方法所在的线程最多等待2000ms,两者的区别在于:
sleep(2000)不释放锁,join(2000)释放锁,因为join()方法内部使用的是wait(),因此会释放锁。看一下join(2000)的源码就知道了,join()其实和join(2000)一样,无非是join(0)而已:
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;
}
}
}
第12行、第20行应该已经很清楚了
而sleep是不会释放锁的
sleep(long)方法不放锁
上面的例子都证明了 join 是放锁的,而sleep是不会放锁的
下面例子证明了join的另一种问题,原因是join是wait实现的,被其它线程唤醒后,会抢锁,而且是优先抢到锁
方法join()之后的代码提前运行-----出现意外
解释意外的发生情况
可以清楚的看到,出现的情况是多种多样的,原因就在于join会抢锁,执行完毕之后,就放锁然后执行锁之后的代码,也是由于线程的随机性,情况多种多样,join不是每次都会抢到锁
java多线程16:join()的使用的更多相关文章
- Java多线程中join、yield、sleep方法详解
在Java多线程编程中,Thread类是其中一个核心和关键的角色.因此,对该类中一些基础常用方法的理解和熟练使用是开发多线程代码的基础.本篇主要总结一下Thread中常用的一些静态方法的含义及代码中的 ...
- JAVA多线程---wait() & join()
题外话: interrupt()方法 并不能中断一个正常运行的线程!!! class myThread extends Thread{ @Override public void run(){ fo ...
- Java多线程16:线程组
线程组 可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的组织结构有点类似于树的形式,如图所示: 线程组的作用是:可以批量管理线程或线程组对象,有效地对线 ...
- 转载:Java多线程中join方法的理解
转载自:http://uule.iteye.com/blog/1101994 thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A ...
- Java多线程的join()
假设在main线程里又起了一个thread1线程,在调用了thread1.start()之后: 如果在main线程里调用了thread1.join(),那么main线程将会block,直到thread ...
- Java多线程中join方法详解
join()方法用于让当前执行线程等待join线程执行结束.其实现原理是不停的检查join线程是否存活,如果join线程存活则让当前线程永远等待. join()方法部分实现细节 while(isAli ...
- Java多线程中join方法的理解
thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B. t.join( ...
- Java多线程学习——join方法的使用
join在线程里面意味着“插队”,哪个线程调用join代表哪个线程插队先执行——但是插谁的队是有讲究了,不是说你可以插到队头去做第一个吃螃蟹的人,而是插到在当前运行线程的前面,比如系统目前运行线程A, ...
- java 多线程 Thread.join子线程结束父线程再运行;join(long):等待超时毫秒数
Join的使用 目的:当子线程运行结束后,父线程才能再继续运行 /** * @ClassName ThreadJoinExample * @projectName: object1 * @author ...
随机推荐
- 优化 App 的启动时间
这是一篇 WWDC 2016 Session 406 的学习笔记,从原理到实践讲述了如何优化 App 的启动时间. App 运行理论 main() 执行前发生的事 Mach-O 格式 虚拟内存基础 M ...
- linux top命令查看内存及多核CPU的使用讲述【转】
转载一下top使用后详细的参数,之前做的笔记找不见了,转载一下,作为以后的使用参考: 原文地址:http://blog.csdn.net/linghao00/article/details/80592 ...
- IT软件外包行业深入分析:现状、前途、趋势、待遇 什么是软件外包 外包公司是怎么工作的 软件外包公司的面试 软件外包公司需要什么样的人
目录: [0] - 为什么要对大学生谈软件外包? [1] - 什么是软件外包? [2] - 软件为什么要外包? [3] - 为什么要承接软件外包 [4] - 做软件外包有前途吗? [5] - 外包公司 ...
- C/C++函数指针(typedef简化定义)
学习要点: 1,函数地址的一般定义和typedef简化定义; 2,函数地址的获取; 3,A函数地址作为B函数参数的传递; 函数存放在内存的代码区域内,它 ...
- WCF Service中HttpContext.Current为null的解决办法
1. 在hosting WCF的web.config中加入: <system.serviceModel> <serviceHostingEnvironment aspNetCompa ...
- 图形对象函数figure() 及 子图创建函数subplot()
1 图像对象创建函数figure 创建图形Creates a new figure, 图形名既可以作为显示在图形窗口标题栏中的文本,也是该对象的名称 也可以通过mp.figure()获取(或激活)已创 ...
- 面试必备:HashMap源码解析(JDK8)
1 概述 本文将从几个常用方法下手,来阅读HashMap的源码. 按照从构造方法->常用API(增.删.改.查)的顺序来阅读源码,并会讲解阅读方法中涉及的一些变量的意义.了解HashMap的特点 ...
- 浅谈cocos2dx(18) 中工厂模式
----我的生活.我的点点滴滴! ! cocos2d-x中也有工厂模式.何为工厂模式,顾名思义就是用来产生产品的,工厂就是用来创建其它类对象的类,我们把这个创建其它类对象的类叫做工厂类.而这些被创建的 ...
- ICDAR 成绩 前5企业和高校
11月20日,有光学字符识别(OCR)领域“奥斯卡”之称的国际文档分析与识别大会(ICDAR)数据集最新结果公布,中国高校及企业包揽排行榜前五. ICDAR2015数据集前五名及框架名称分别是:云从科 ...
- Fast Algorithm To Find Unique Items in JavaScript Array
When I had the requirement to remove duplicate items from a very large array, I found out that the c ...