Java线程的join操作有什么作用?

Wesley13
• 阅读 261

计算机为了提升CPU使用效率和交互性而引入了并发机制,任务的执行也抽象成了线程,并发机制让一个CPU能够轮流执行多个线程,从宏观上看多个线程就像是同时执行一样。并发使得线程的执行顺序不容易控制,而实际工程中很多场景都会涉及某个线程需要依赖另外一个或几个线程的执行结果,这就要被依赖的线程需要先执行完,这时就需要join操作。比如下面的场景,假如要计算A+B的结果且A和B的计算都比较耗时,那么我们将B的计算分给另外一个线程,而线程一则负责A的计算。如果线程一先执行完则它要等待线程二,直到线程二计算出B的结果后线程一才继续往下执行,去计算A+B。

Java线程的join操作有什么作用?

01

Join 操作

从上面的介绍看来join操作类似于前面讲解的线程通知等待机制,的确是这样,join操作为我们提供了等待通知机制。某个线程可以通过调用join操作来等待另外一个线程的执行,直到另外一个线程执行完毕。我们来看下面的例子,线程t1首先创建了线程t2并启动该线程,接着线程t1继续创建线程t3,然后线程t1调用t2.join()和t3.join()进入等待状态。自此线程t1进入等待状态,而线程t2和线程t3一直执行,到它们俩都执行完毕后线程t1才会继续往下执行。

Java线程的join操作有什么作用?

02

Join 案例

下面是一个简单的例子,主线程创建了线程t2并启动它,t2中通过睡眠三秒来模拟耗时计算,主线程中调用了t2.join()表示要等到t2执行完毕后才往下执行,也就是三秒后主线程才输出“got t2's result.”。

Java线程的join操作有什么作用?

03

Join 的中断机制

从上一个例子可以看到主线程调用t2.join()后会一直处于等待状态,假如t2一直不执行完则主线程会一直等待下去。然而join操作是支持中断的,可以通过中断来解除join的阻塞。该例子中t2启动后会睡眠60秒,随后t3启动后主线程就进入等待状态。t3在睡眠三秒后就将主线程的中断标示设置为true,即进行中断操作。主线程解除阻塞,并输出“t3 has interrupted main thread.”。

Java线程的join操作有什么作用?

04

 Join 的超时机制 

join操作默认会无限等待,也就是说不管另一个线程执行多久都将等待其运行完。但如果我们希望等待的时间是有期限的话则可以传入超时时间,一旦等待超过该指定时间则会解除阻塞。下面的例子中,与前面不同的地方在于其调用了t2.join(3000),也就是join的超时为3秒。t2会睡眠60秒,但主线程只会等待3秒就解除阻塞,然后输出“join timeout.”。

Java线程的join操作有什么作用?

05

 Join 的实现原理 

最后我们来看join操作的实现原理,对应的核心源码为java.lang.Thread类中,不带参数的join方法实际上间接调用了join(0),所以主要逻辑在join(long millis)方法中。如果传入的超时时间为负数则会抛出非法参数异常,如果超时时间为0则调用wait(0)方法,该方法会使当前线程一直等待,直到其它线程进行了notify通知。也就是说JVM会负责在线程退出前去进行通知操作,从而让join解除等待状态。如果超时时间大于0则计算最长的等待时间,然后调用wait(delay)使线程进入等待状态,传入的参数使得在等待超时后能解除等待状态。关于wait和notify的模式和机制,先前有针对源码、案例以及实现原理分享过,可以查看 Java并发编程:多线程如何实现阻塞与唤醒

Java线程的join操作有什么作用?

- END -

Java线程的join操作有什么作用?

本文分享自微信公众号 - 码农架构(iByteCoding)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
2年前
java并发中CountDownLatch的使用
java并发中CountDownLatch的使用在java并发中,控制共享变量的访问非常重要,有时候我们也想控制并发线程的执行顺序,比如:等待所有线程都执行完毕之后再执行另外的线程,或者等所有线程都准备好了才开始所有线程的执行等。这个时候我们就可以使用到CountDownLatch。简单点讲,CountDownLatch存有一个放在QueuedS
浩浩 浩浩
3年前
android 面试题总结
Java部分一、多线程 Join() 线程加入,执行此方法的线程优先使用cpu Yeild() 线程释放资源使所有线程能有相等的机会使用cpu Sleep()相当于让线程睡眠,交出CPU,让CPU去执行其他的任务(不会释放锁)。Wait()方法会让线程进入阻塞状态,并且会释放线程占有的锁,并交出CPU执行权限。
Wesley13 Wesley13
2年前
java并发编程
!(https://oscimg.oschina.net/oscnet/2f1567f1fe639e22278f5fb1eed675cb9f2.jpg)如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。那么有没有一种办法使得线程可以复用,就是执行完一
Wesley13 Wesley13
2年前
java多线程的3种实现方式
多线程相关的问题1.什么是进程?​正在执行的程序2.什么是线程?​进程的子单位,一个能够完成独立功能的执行路径3.为什么需要开启多线程?当执行某些耗时操作的任务的时候需要开启多线程,防止线程阻塞能够让两个任务看起来像是在同时执行
Stella981 Stella981
2年前
Python进程、线程、协程的对比
1\.执行过程每个线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在进程中,由进程提供多个线程执行控制。每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。协程,又称微线程,Coroutine。执行过程中,在子程序内部可中断,然后转而
Wesley13 Wesley13
2年前
Java高级教程02
\TOC\1.Java线程1.1.多线程和多进程多进程:操作系统能够同时进行多个任务:每个app(word,播放器,浏览器)可以同时运行多线程:同一应用程序中哟多个顺序流同时执行线程是进程中的一部分1.2.线程的执行过程:!(
Stella981 Stella981
2年前
Python并发(二)
并发是指一次处理多件事,而并行是指一次做多件事。二者不同,但互相有联系。打个比方:像Python的多线程,就是并发,因为Python的解释器GIL是线程不安全的,一次只允许执行一个线程的Python字节码,我们在使用多线程时,看上去像很多个任务同时进行,但实际上但一个线程在执行的时候,其他线程是处于休眠状态的。而在多CPU的服务器上,Java或Go的多线程,
Wesley13 Wesley13
2年前
Java分布式锁看这篇就够了
\什么是锁?在单进程的系统中,当存在多个线程可以同时改变某个变量(可变共享变量)时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量。而同步的本质是通过锁来实现的。为了实现多个线程在一个时刻同一个代码块只能有一个线程可执行,那么需要在某个地方做个标记,这个标记必须每个线程都能看到
京东云开发者 京东云开发者
7个月前
深入浅出线程池 | 京东云技术团队
一、线程1、什么是线程线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。2、如何创建线程2.1、JAVA中
京东云开发者 京东云开发者
5个月前
ThreadPoolExecutor线程池内部处理浅析 | 京东物流技术团队
我们知道如果程序中并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束时,会因为频繁创建线程而大大降低系统的效率,因此出现了线程池的使用方式,它可以提前创建好线程来执行任务。本文主要通过java的ThreadPoolExecutor来查看线程池