大家好,欢迎来到IT知识分享网。
先看例子:
网上的例子
/** * join的用法,哪个线程调用join哪个线程就插队先执行 */
public class JoinTest {
public static void main(String[] args) {
//开启学习线程
Study study = new Study();
study.setName("学习线程------");
study.start();
try {
study.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"-----学习完毕,准备干别的事");
}
}
class Study extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "我想学习study 多线程 join 用法,但是没有资料,开始百度找资料");
Baidu baidu = new Baidu();
baidu.setName("百度线程------");
baidu.start();
try {
baidu.join(); //先去百度找资料,然后才能学习
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "开始学习");
}
}
class Baidu extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始百度,找资料中");
for (int i = 1; i <= 2; i++) {
System.out.println(Thread.currentThread().getName() + i + "秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "找到资料");
}
}
运行效果:
学习线程------我想学习study 多线程 join 用法,但是没有资料,开始百度找资料
百度线程------开始百度,找资料中
百度线程------1秒
百度线程------2秒
百度线程------找到资料
学习线程------开始学习
main-----学习完毕,准备干别的事
结论:
1、哪个线程调用join代表哪个线程要插在当前线程的前面执行。也就是说哪个线程执行这句代码,哪个线程就被阻塞。其他线程不受影响。比如把study.join();去掉,主线程会先执行完。
2、join 源码还是调用的是wait方法进行等待。然后等线程执行完会调用notify,或者notifyAll 方法。所以使用join自己不要轻易调用wait,notify,notifyAll 方法。
以下为join 源码注释翻译:
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.
这个实现使用了一个循环{@code This。等待}调用条件为{@code this.isAlive}。当一个线程终止{@code这个。调用notifyAll}方法。建议应用程序不要在{@code Thread}实例上使用{@code wait}、{@code notify}或{@code notifyAll}。
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;
}
}
}
3、join 加上时间参数的话最后时间还是加在wait方法上,所以是让线程等待多长时间。等待时间超时后就不再等待了。
4、join 适用于需要控制线程执行顺序的场景中。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/10777.html