一、sleep()
1.1 sleep()简介
sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”。在线程重新被唤醒时,它会由“阻塞状态”变成“就绪状态",从而等待cpu的调度执行。
sleep()会指定休眠时间,线程休眠的时间会大于/等于该休眠时间。
1.2 sleep()的使用
Thread.sleep(100);
1.3 sleep()与wait()区别
wait 和 sleep都会造成某种形式的暂停。wait()用于线程间通信,作用是让当前线程由“运行状态”进入”等待(阻塞)状态”;而sleep()的作用是让当前线程由“运行状态”进入到“休眠(阻塞)状态”。
wait()会释放对象的同步锁;而sleep()则不会释放锁,仅仅释放CPU资源或者让当前线程停止执行一段时间。
二、join()
2.1 join()简介
如果一个线程A执行了thread.join()语句,其含义是:当前线程A等待thread线程终止之后才从thread.join()返回。
线程Thread除了提供join()方法之外,还提供了join(long millis)和join(long millis,int nanos)两个具备超时特性的方法。这两个超时方法表示,如果线程thread在给定的超时时间里没有终止,那么将会从该超时方法中返回。
2.2 join()示例
有三个线程T1,T2,T3,怎么确保它们按顺序执行?
/**
* 有三个线程T1,T2,T3,怎么确保它们按顺序执行?
* join()
* @author lc 2017/5/3
*/
public class TestJoin {
public static void main(String[] args) {
final Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
},"T1");
final Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
},"T2");
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
},"T3");
t3.start();
t2.start();
// try {
// Thread.sleep(300);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
t1.start();
}
}
输出结果:T1
T2
T3
2.3 join()源码
1.join()方法
public final void join() throws InterruptedException {
join(0); //实际是调用join(long millis)
}
2.join(long millis)方法
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");
}
//join()方法。join(0)
if (millis == 0) {
while (isAlive()) {//判断本线程是否为活动状态(活动状态指线程已经启动且尚未终止)
wait(0); //等待
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
三、yield()
3.1 yield()简介
yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权。但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权,也有可能是当前线程又进入到“运行状态”继续运行!
3.2 yield()的使用
Thread.yield();
3.3 为什么Thread类的sleep()和yield()方法是静态的?
Thread类的sleep()和yield()方法将在当前正在执行的线程上运行,其他处于等待状态的线程调用这些方法是没有意义的。将这些方法设计成静态的,可以在当前正在执行的线程中工作,并避免程序员错误的认为可以在其他非运行线程调用这些方法。
参考资料
《java并发编程的艺术》