Thread中suspend与resume为什么被废弃

138 阅读1分钟

笔记是在看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会更加安全