join
等待线程执行终止
join方法是Thread方法直接提供的方法,返回值是void
适用场景:
需要线程有序地执行,而不是被动随机等待CPU分配时间片。如多个线程加载资源,需要等待资源全部资源加载完毕再汇总执行下个操作。
sleep
顾名思义sleep方法是让线程休眠的方法,当线程调用了sleep方法后,调用线程会暂时让出指定时间的执行权,不参与CPU调度,但是不会释放锁。等待时间到了,线程就会处于就绪状态,然后参与CPU调度。
如果在睡眠期间其他线程调用了该线程的interrupt()方法中断了该线程,则该线程会在调用sleep方法的地方抛出InterruptedException异常。
看个小例子:
public class SleepAndJoin {
// 创建一个独占锁
public static Lock lock = new ReentrantLock();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
System.out.println("t1 is sleep");
Thread.sleep(1000);
System.out.println("t1 is awake");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
System.out.println("t1 is over");
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
System.out.println("t2 is sleep");
Thread.sleep(1000);
System.out.println("t2 is awake");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
System.out.println("t2 is over");
}
});
// 启动线程
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行结果
通过多次执行,都是这个结果。
从此可以分析出:
1.线程1总比线程2先执行:join
2.线程在执行过程中没有释放独占锁:总是等线程执行结束才释放