java基础知识回顾之java Thread类学习(十一)--join方法的理解
以下面例子说明下面的源码:main 线程 和 A线程,A线程是main线程创建并且启动的,main线程优先级比较高,正在执行;
这个时候main线程调用A.join()之后,main线程一直等待,直到A线程运行完毕,main线程才运行。
join方法的源码:
* Waits at most {@code millis} milliseconds for this thread to
* die. A timeout of {@code 0} means to wait forever.
*
* <p> This implementation uses a loop of {@code this.wait} calls
* conditioned on {@code this.isAlive}. As a thread terminates the
* {@code this.notifyAll} method is invoked. It is recommended that
* applications not use {@code wait}, {@code notify}, or
* {@code notifyAll} on {@code Thread} instances.
*
* @param millis
* the time to wait in milliseconds
*
* @throws IllegalArgumentException
* if the value of {@code millis} is negative
*
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
// 加锁当前线程
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) {
//A线程是start,在运行中
while (isAlive()) {
//main线程等待
wait(0);
}
} else {
//join(timeOut)的情况
while (isAlive()) {
//根据当前timeout的时间-now 是否<=0进行判断,主线程是否继续阻塞等待
long delay = millis - now;
//等待超时时间到了,则主线程不阻塞了,等待结束
if (delay <= 0) {
break;
}
wait(delay);
//子线程从循环开始到现在运行的时间
now = System.currentTimeMillis() - base;
}
}
}
给一个例子来理解:
package concurrentMy.joins; /**
*
* @author Administrator
*
* main 线程 和 A线程,A线程是main线程创建并且启动的,main线程优先级比较高,正在执行;
* 这个时候main线程调用A.join()之后,main线程一直等待,直到A线程运行完毕,main线程才运行
*
*/
class ThreadA extends Thread { public ThreadA(String name){
super(name);
} @Override
public void run() { for (int i = 0; i < 20; i++) {
// 复写父类的toString方法, 返回该线程的字符串表示形式,包括线程名称、优先级和线程组。
System.out.println(Thread.currentThread().getName() + "-" + i); }
} } public class JoinDemo { /**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
ThreadA A = new ThreadA("线程A");
A.start();
A.join(); //A线程加入到“main线程”中,main线程一直等待,直到A线程执行完毕,main线程才运行
System.out.println(Thread.currentThread().getName() + "执行");
System.out.println(Thread.currentThread().getName() + "执行终止"); } }
输出结果:
线程A-0
线程A-1
线程A-2
线程A-3
线程A-4
线程A-5
线程A-6
线程A-7
线程A-8
线程A-9
线程A-10
线程A-11
线程A-12
线程A-13
线程A-14
线程A-15
线程A-16
线程A-17
线程A-18
线程A-19
main执行
main执行终止
代码运行整个过程说明入下图:

java基础知识回顾之java Thread类学习(十一)--join方法的理解的更多相关文章
- java基础知识回顾之---java String final类普通方法
辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /* * 按照面向对象的思想对字符串进行功能分类. * ...
- java基础知识回顾之java Thread类学习(三)--java线程实现常见的两种方式实现好处:
总结:实现Runnable接口比继承Thread类更有优势: 1.因为java只能单继承,实现Runnable接口可以避免单继承的局限性 2.继承Thread类,多个线程不能处理或者共享同一个资源,但 ...
- java基础知识回顾之java Thread类学习(十)--线程的状态以及转化使用的方法介绍
线程的概述: 线程是程序的多个执行路径,执行调度的单位,依托于进程存在.线程不仅可以共享进程的内存,而且还拥有一个属于自己的内存空间,这段内存空间叫做线程栈,是建立线程的时候由系 ...
- java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)
1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以 ...
- java基础知识回顾之java Thread类--java线程实现常见的两种方式实现Runnable接口(二)
创建线程的第二中方式: /** * 步骤: 1定义类实现Runnable接口 2.实现Runnable接口中的run方法. 3.通过Thread类建立线程对象,并将Run ...
- java基础知识回顾之java集合类-Properties集合
/** java.lang.Object |--java.util.Dictionary<K,V> |--java.util.Hashtable<Object,Obje ...
- java基础知识回顾之java Thread类学习(八)--java.util.concurrent.locks(JDK1.5)与synchronized异同讲解
看API文档介绍几个方法: JDK1.5中提供了多线程的升级解决方案: 特点: 1.将同步synchronized显示的替换成Lock 2.接口Conditio ...
- java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)
*java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时 ...
- java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)
上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // ...
随机推荐
- hashcode与字符串
问题1. 不同的字符串可能会有相同的HashCode吗? hashcode是用来判断两个字符串是否相等的依据,不同的字符串不可能有相同的hashcode,但不同的hashCode经过与长度的取余,就很 ...
- redis安装步骤
7.1创建业务安装用户 安装和配置Redis软件时,需要使用redis用户登录服务器进行相关操作,因此需要创建redis的业务安装用户组和redis的业务安装用户.此操作在主备机上同时进行. 创建用户 ...
- unity 全屏乱影 BlitMultiTap
http://m.blog.csdn.net/blog/stalendp/40859441 官方例子AngryBots的链接地址:http://u3d.as/content/unity-technol ...
- Centos 5.x/6.x 配置163网易yum源
Centos系统默认都是系统自带的yum源,国内用户用yum源安装比较慢,为了提高效率,一般我们会配置国内的yum源.国内比较好的yum源有网易yum源.搜狐yum源等. 我感觉网易的yum源比较好用 ...
- php中文字符串翻转
转自:http://www.oschina.net/code/snippet_613962_17070 <?php header("content-type:text/html;cha ...
- Lua函数之一
LUA函数之一 函数声明: function foo(arguments) statements end 1.函数调用 调用函数的时候,如果参数列表为空,必须使用()表明是函数调用,例如: os.da ...
- win7 vmware 无法使用usb
只有在win7下才会有这个问题,在xp下没有. 原因是: win7的主机上禁用了vmare usb arbitration(仲裁) service. 在主机上启用这个服务 重启即可. 如果无法启用vm ...
- 移动端Web开发注意点
不用考虑浏览器兼容性 移动端开发主要对象是手持设备,其中绝大部分是IOS和Android系统,so,在开发此类页面时不必纠结IE和其他一些2B浏览器的兼容性,webkit是本次开发重点. 当然,不同版 ...
- form表单那点事儿(上) 基础篇
form表单那点事儿(上) 基础篇 做为html中最为常见,应用最广泛的标签之一,form常伴随前端左右.了解更深,用的更顺. 目录: 表单属性 表单元素 常识 模拟外观 表单属性 这个表单展示了fo ...
- 在表单(input)中id和name的区别
但是name在以下用途是不能替代的: 1. 表单(form)的控件名,提交的数据都用控件的name而不是id来控制.因为有许多name会同时对应多个控件,比如checkbox和radio,而id必须是 ...