多线程中让线程等待的方法有很多种,下面我们就来分析这些方法的作用和区别
public static native void yield()
源码注释翻译
- 向调度器发起一个示意,表明当前线程乐意放弃CPU。调度器可以忽略这一提示。
- Yield是一种启发式的尝试,用于改进线程之间的相对进展,否则会过度使用CPU.它的使用应与详细的分析和基准测试相结合,以确保它实际上达到期望的效果.
- Yield方法很少有场景去是和使用.它可能对调试或测试目的很有用,它可能有助于重现因竞争条件而产生的错误.在设计并发控制结构(例如{@link java.util.concurrent.locks}包中的结构)时,它也可能很有用.
使用说明
yield的方法一般不怎么使用,当前线上程调用了yield方法后只是表示此乐意放弃处理器的使用权,调度器可以先去处理其他的程序.但是因为操作系统的调度室不确定的,并且线程是有优先级的,有可能会A线程调用完yield()以后,等会A线程还是会被执行.** 一般用于调试程序和多线程之间调用的问题**
public final void join() throws InterruptedException
源码注释
- 等待这个线程死亡.
- 调用此方法的行为与调用完全相同
源码:
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;
}
}
}
例子
// 创建Thread子类对象,即创建了线程对象。
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.所以输出结果是: