Java 多线程基础(九)join() 方法
Java 多线程基础(九)join 方法
一、join() 方法介绍
join() 定义 Thread 类中的,作用是:把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。如:线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。
Thread 类中分别定义了: join() 、join(long millis) 和 join(long millis, int nanos) 三个方法。
①、join():等待线程t执行完毕。
②、join(long millis):等待 t 线程,等待时间是 millis 毫秒。
③、join(long millis, int nanos) :等待 t 线程,等待时间是 millis 毫秒 + nanos 纳秒。
二、join() 示例
public class JoinThread {
public static void main(String[] args) {
try {
Thread t1 = new MyThread("t1");// 新建线程t1
t1.start();// 启动线程
t1.join(); // 将线程t1加入到主线程main中,并且主线程main()会等待它的完成
System.out.println(Thread.currentThread().getName() + " main end.");
}catch(Exception e) {
e.printStackTrace();
}
}
static class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
public void run() {
System.out.println(Thread.currentThread().getName() + " run start.");
for(int i = 0;i < 10000;i++)
;
System.out.println(Thread.currentThread().getName() + " run end.");
}
}
}
// 运行结果
t1 run start.
t1 run end.
main main end.
说明:
①、在“主线程main”中通过 new MyThread("t1") 新建“线程t1”。 接着,通过 t1.start() 启动“线程t1”,并执行t1.join()。
②、执行t1.join()之后,“主线程main”会进入“阻塞状态”等待t1运行结束。“子线程t1”结束之后,会唤醒“主线程main”,“主线程”重新获取cpu执行权,继续运行。
具体过程图解:

三、join() 解析(基于JDK 1.8)
public final void join() throws InterruptedException {
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;
}
}
}
public final synchronized void join(long millis, int nanos) throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) { // 纳秒值范围在 (0 ~ 999999]
throw new IllegalArgumentException("nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
join(millis);
}
上面源码是在Thread 类中定义的: join() 、join(long millis) 和 join(long millis, int nanos) 三个方法。
从上面代码中可以看到,最主要的是 join(long millis) 方法,从该方法中可以发现:当传递的 millis == 0 时,会进入while(isAlive())循环;即只要子线程是活的,主线程就不停的等待。
问题:
虽然t1.join() 被调用的地方是发生在“main主线程”中,但是 t1.join() 是通过“子线程t1”去调用的 join()。那么,join() 方法中的 isAlive() 应该是判断“子线程t1”是不是 Alive 状态;对应的 wait(0) 也应该是“让子线程t1”等待才对。但如果是这样的话,t1.join() 的作用怎么可能是“让主线程等待,直到子线程s完成为止”呢,应该是让"子线程等待才对(因为调用子线程对象 t1 的 wait 方法嘛)"?
答案:
wait() 的作用是让“当前线程”等待,而这里的“当前线程”是指当前在CPU上运行的线程。所以,虽然是调用子线程的 wait() 方法,但是它是通过“主线程”去调用的;所以,休眠的是主线程,而不是“子线程”!
Java 多线程基础(九)join() 方法的更多相关文章
- Java多线程中的join()方法
一.join()方法介绍 join() 定义在Thread.java中.join()方法把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的join( ...
- 浅谈Java多线程中的join方法
先上代码 新建一个Thread,代码如下: package com.thread.test; public class MyThread extends Thread { private String ...
- Java多线程中的join方法
新建一个Thread,代码如下: package com.thread.test; public class MyThread extends Thread { private String name ...
- java多线程中关于join方法的使用
Thread的非静态方法join()让一个线程B"加入"到另外一个线程A的尾部.在A执行完毕之前,B不能工作.例如: Thread t = new MyThread ...
- Java多线程10:join()方法
一.前言 通过一个简单的例子引入join()方法 public class Thread01 extends Thread{ @Override public void run() { for(int ...
- 多线程基础知识---join方法
join方法的作用 thread.join()方法用于把指定的线程加入到当前线程中,把当前线程的CPU执行时间让给另一个线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继 ...
- Java并发编程--多线程中的join方法详解
Java Thread中, join()方法主要是让调用该方法的thread在完成run方法里面的部分后, 再执行join()方法后面的代码 例如:定义一个People类,run方法是输出姓名年龄. ...
- [转]Java多线程干货系列—(一)Java多线程基础
Java多线程干货系列—(一)Java多线程基础 字数7618 阅读1875 评论21 喜欢86 前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们 ...
- Java 多线程——基础知识
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
随机推荐
- 5.Linux的启动过程和系统指令
1.Linux的启动过程 作为一台计算机,启动它的第一步是加电自检,也就是给电脑用电然后按电源按钮开机.加电之后的运行步骤:(1)加载bios,然后检查硬盘信息 (2)读取MBR的配置(MBR就是硬盘 ...
- Channels集成到Django消息实时推送
channel架构图 InterFace Server:负责对协议进行解析,将不同的协议分发到不同的Channel Channel Layer:频道层,可以是一个FIFO队列,通常使用Redis Dj ...
- [SD心灵鸡汤]007.每月一则 - 2015.11
1.不要因为世界太过复杂,而背叛了你的单纯. 2.人的一生要疯狂一次,无论是为一个人,一段情,一段路途或一个梦想. 3.时间真的很神奇,你永远不知道它会如何改变你.换句话说:以前难吃的蔬菜.苦涩的啤酒 ...
- [翔哥高手无敌之路]0-002.如何提取apk中的信息?
面对一款apk软件,我们如何去获取它的信息,如何获取它的版本号,包名,或者ID,用户权限,这些信息都隐藏在apk包中的AndroidManifest.xml文件中,解开它我们就能获取任何想要的信息.但 ...
- Rocket - util - AsyncQueue
https://mp.weixin.qq.com/s/6McbqOKM4fu4J5vdpZvxKw 简单介绍异步队列(AsyncQueue)的实现. 0. 异步队列 异步队列的两端分 ...
- SPA页面
背景: 单页 Web 应用 (single-page application 简称为 SPA) 是一种特殊的 Web 应用,它将所有的活动均局限于一个Web页面中:这就表示Web应用被加载出来之后,W ...
- ERROR: ...hbase.PleaseHoldException: Master is initializing
同学升级HBase后遇到这个问题,hbase shell,status就可以看到 ERROR: -hbase.PleaseHoldException: Master is initializing 解 ...
- Java实现 LeetCode 519 随机翻转矩阵
519. 随机翻转矩阵 题中给出一个 n 行 n 列的二维矩阵 (n_rows,n_cols),且所有值被初始化为 0.要求编写一个 flip 函数,均匀随机的将矩阵中的 0 变为 1,并返回该值的位 ...
- Java实现 蓝桥杯VIP 算法训练 判断字符位置
判定字符位置 时间限制: 1Sec 内存限制: 128MB 提交: 487 解决: 251 题目描述 返回给定字符串s中元音字母的首次出现位置.英语元音字母只有'a'.'e'.'i'.'o'.'u'五 ...
- Java实现 蓝桥杯VIP 算法训练 输出米字形
例如:n=3时,包含A,B,C:n=4时,包含A,B,C,D. 矩阵的正中间为n个字母中字典序最大的那个,从这个字母开始,沿着西北.正北.东北.正西.正东.西南.正南.东南八个方向各有一条由大写字母组 ...