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() { // ...
随机推荐
- 浅谈datagrid详细操作单元格样式
http://www.easyui.info/archives/470.html 今天有朋友问到:“如果设置列标题居中而列内容居右显示?”,仔细查了一下api,目前版本提供了两个相关的列属性,alig ...
- Hibernate动态更新
Hibernate一级缓存: Hibernate有一级和二级缓存.一级缓存就是Session. 在Hibernate启动的时候,SessionFactory解析映射文件的时候,会根据映射文件中的字段生 ...
- 使用I/O 系统调用--copy.c
作为Linux/Unix 系统编程入门,小生按照自己可以理解的方式,改写了源copy.c源代码来自:Linux/UNIX 系统编程手册 上册 P57 #include <stdio.h>/ ...
- Jquery中的 height(), innerHeight() outerHeight()区别
jQuery中的 height innerHeight outerHeight区别 标准浏览器下: height:高度 innerHeight:高度+补白 outerHeight:高度+补白+边框,参 ...
- 关于Base64编码
作者:唐风 Base 64是一种比较古老的编码方式,在通信中非常常见.它实现很简单. What? "Base64是一种基于64个可打印字符来表示二进制数据的表示方法(来自维基)". ...
- explode 和 implode
<?php $str = "HellooooLAAAAAALleeellll33432ll!"; //字符拆分,当2个“l”并列出现,元素结果是空格“ ”,所有的结果是一维数 ...
- 想在BD自然排名中脱颖而出吗?加张合适的图片吧!
经常在BD或gg搜索不难发现有些搜索结果会带有缩略图,类似下图,图文搭配,看着不累 在一大排搜索结果中,都是文字的话,还没认真看就感觉累,如果在这些搜索结果中突然出现一条图文结合的条目,是不是有耳目一 ...
- unity3d进行脚本资源打包加载
原地址:http://www.cnblogs.com/hisiqi/p/3204752.html 本文记录如何通过unity3d进行脚本资源打包加载 1.创建TestDll.cs文件 public c ...
- easyui 删除行bug
easyui删除行,出现了bug.(经常使用这个框架的人几乎都会遇到) 我也非常纳闷,今天特地试了很久. 最后发现,如果是自己datagrid('getRows') 然后迭代出来,最后算出行号,可以成 ...
- windows 程序的本体与操作系统之间的关系
WinMain(hInst,hPrev,……) { MSG msg; RegisterClass(……); CreateWindow(……); ShowWindow(……); UpdateWindow ...