Java多线程通信Suspend和Resume,为什么被弃用,如何导致死锁

Suspend和Resume作用

  • suspend: 让线程挂起,暂停,程序停止往下执行。
  • resume: 唤醒被suspend的程序,让程序继续执行。

代码示例

一个是消息发送者,一个是消息接受着,当消息发送者有消息了,马上通知接受者接受消息。


    /**
     * 测试 suspend 和 resume
     */
    public void testsSuspendAndResume() {
    
    

        Thread consumer = new Thread(() -> {
    
    

            while (true) {
    
    
                while (message == null) {
    
    
                    System.out.println("等待接受消息");
                    Thread.currentThread().suspend();
                }
                System.out.println("接受消息 => " + message);
                message = null;
            }

        });
        consumer.start();

        Thread producer = new Thread(() -> {
    
    
            while (true) {
    
    
                try {
    
    
                    Thread.sleep(3000);
                    message = "Hello , this is " + i++;
                    consumer.resume();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        });
        producer.start();
    }

Suspend和Resume为什么被弃用

官方解释

Thread.suspend is inherently deadlock-prone. If the target thread holds a lock on the monitor protecting a critical system resource when it is suspended, no thread can access this resource until the target thread is resumed. If the thread that would resume the target thread attempts to lock this monitor prior to calling resume, deadlock results. Such deadlocks typically manifest themselves as “frozen” processes.

  • 因为suspend本质上容易出现死锁
  • 当一个线程使用锁时使用suspend,是不会释放锁的,其他线程会获取不到这个锁

死锁代码示例

当消费者获取this锁suspend,因为suspend,不会释放锁,所以然后生产者就一直在获取锁的状态,无法生产消息,最终导致死锁。

 /**
     * 测试Suspend Resume 死锁
     * <p>
     * 
     */
    public void testSuspendAndResumeDeadLockOfSync() {
    
    
        Thread consumer = new Thread(() -> {
    
    
            while (true) {
    
    
                synchronized (this) {
    
    
                    while (message == null) {
    
    
                        System.out.println("等待接受消息");
                        Thread.currentThread().suspend();
                    }
                    System.out.println("接受消息 => " + message);
                    message = null;
                }
            }
        });
        consumer.start();

        Thread producer = new Thread(() -> {
    
    
            while (true) {
    
    
                synchronized (this) {
    
    
                    try {
    
    
                        Thread.sleep(3000);
                        message = "Hello , this is " + i++;
                        consumer.resume();
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        });
        producer.start();
    }


参考地址

猜你喜欢

转载自blog.csdn.net/qq_36325121/article/details/108794311