版权声明:分享,转载原创文章,麻烦注明一下出处~谢谢 https://blog.csdn.net/sc9018181134/article/details/82289605
前言:
多线程中让线程等待的方法有很多种,下面我们就来分析一些这些方法的作用和区别.
1. public static native void yield();
1.1 源码注释翻译:
(1). 向调度程器发起一个示意,表明当前线程乐意去放弃当前使用的处理器.调度器可以忽略这一提示.
(2). Yield是一种启发式的尝试,用于改进线程之间的相对进展,否则会过度使用CPU.它的使用应与详细的分析和基准测试相结合,以确保它实际上达到期望的效果.
(3). Yield方法很少有场景去是和使用.它可能对调试或测试目的很有用,它可能有助于重现因竞争条件而产生的错误.在设计并发控制结构(例如{@link java.util.concurrent.locks}包中的结构)时,它也可能很有用.
1.2 使用说明:
yield的方法一般不怎么使用,当前线上程调用了yield方法后只是表示此乐意放弃处理器的使用权,调度器可以先去处理其他的程序.但是因为操作系统的调度室不确定的,并且线程是有优先级的,有可能会A线程调用完yield()以后,等会A线程还是会被执行. 一般用于调试程序和多线程之间调用的问题.
2. public final void join() throws InterruptedException
2.1 源码注释:
(1). 等待这个线程死亡.
(2). 调用此方法的行为与调用完全相同
源码:
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;
}
}
}
可以看出join()调用的是join(long millis),join(0)表示永远等待,直到该线程结束.join(long millis)的判断条件是该线程是否存活.存活则调用wait方法.(wait是object类的方法)
2.2 实践例子:
public class JoinTest {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(
()->{
System.out.println(Thread.currentThread().getName() + "启动");
System.out.println(Thread.currentThread().getName() + "结束");
}
);
Thread b = new Thread(
()->{
System.out.println(Thread.currentThread().getName() + "启动");
try {
System.out.println(Thread.currentThread().getName() + "sleep 3 秒");
Thread.currentThread().sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "结束");
}
);
b.start();
// b.join();
a.start();
}
}
这个程序当b没有join时,b肯定是后执行完毕,因为b休眠了2秒.
输出结果:
如果加上了join,则main的线程会等待b执行完毕以后,在继续往下执行a.所以输出结果是: