笔记是在看Doug Lea的The java.util.concurrent Synchronizer Framework一文中关于选择框架中必不可少的阻塞组件的思考中,提到的关于Thread.suspend()/Thread.resume()和LockSupport.park()/LockSupport.unpark()两组阻塞组件的优缺点之后,有所获,在此记录
resume失效
- Doug Lea提到,当Thread.resume()方法的调用在Thread.suspend()方法之前的时候,Thread.resume并不会生效。线程并发场景下的无序性,coding的不谨慎是可能导致resume的调用在suspend调用之前的原因之一
code示例
public class Demo {
private static class MyTask implements Runnable {
@Override
@SneakyThrows
public void run() {
//保证resume在suspend之前执行
Thread.sleep(3000L);
Thread.suspend();
System.out.println("my task has been execute")
}
}
public static void main(String[] args) {
Thread myTask = new Thread(new MyTask());
myTask.start();
myTask.resume();
System.out.println("thread resume methods has been execute");
}
}
- 最后执行效果 -> 只输出了"thread resume methods has been execute"。因此可以说明Doug Lea在文中的阐述:Thread.resume()在Thread.suspend()之前执行,那resume()并不会产生任何效果
LockSupport.unpark的出现
- LockSupport则能够解决并发情况下线程执行的无序性导致的Thread.resume的实效
code示例
public class Demo {
private static class MyTask implements Runnable {
@Override
@SneakyThrows
public void run() {
Thread.sleep(3000L);
LockSupport.park();
System.out.println("my task has been execute");
}
public static void main(String[] args) {
Thread myTask = new Thread(new MyTask());
myTask.start();
LockSupport.unpark(myTask);
System.out.println("thread resume methods has been execute");
}
}
resume的失效在某些场景下可能引发DeadLock
- 如果被suspend阻塞的线程持有锁(synchronized)的话,进而可能引发死锁,因为suspend并不会释放掉线程持有的所有锁
code示例
public class Demo {
private Integer LOCK = 1;
private static class MyTask implements Runnable {
@Override
@SneakyThrows
public void run() {
//保证resume在suspend之前执行
Thread.sleep(3000L);
synchronized(LOCK) {
Thread.suspend();
}
}
}
public static void main(String[] args) {
Thread myTask = new Thread(new MyTask());
myTask.start();
myTask.resume();
synchronized(LOCK) {
//do something
}
}
}
- LockSupport使用不当也会产生死锁,只是相对于Thread自带的suspend/resume方法,LockSupoort会更加安全