线程的挂起跟恢复

什么是线程间通信?

线程的挂起操作实质上就是使线程进入“非执行”状态下,在这个状态下CPU不会分给线程时间片,进入这个状态可以用来暂停一个线程的运行。在线程挂起后,可以通过重新唤醒线程来使其恢复运行

为什么要挂起线程?

cpu分配的时间片非常短、同时也非常严重。避免资源的浪费。

如何挂起线程?

被废弃的方法
  • thread.suspend()该方法不会释放线程所占用的资源。如果使用该方法将某个线程挂起,则可能会使其他等待资源的线程死锁
  • thread.resume()方法本身并无问题,但不能独立于 suspend() 方法存在
  • 例子
    • 基础的暂停的演示
      package com.xdclass.thread.hang;
      
      /**
       * 挂起操作的Demo
       */
      public class SuspendDemo implements Runnable {
      
          @Override
          public void run() {
              System.out.println(Thread.currentThread().getName()+"执行run方法,准备调用suspend方法");
              //挂起线程
              Thread.currentThread().suspend();
              System.out.println(Thread.currentThread().getName()+"执行run方法,调用suspend方法结束");
      
          }
      
          public static void main(String[] args) throws InterruptedException {
              Thread thread = new Thread(new SuspendDemo());
              thread.start();
              Thread.sleep(3000L);
              //对线程进行唤醒操作
              thread.resume();
          }
      }
    • 制作死锁的演示
      package com.xdclass.thread.hang;
      
      /**
       * suspend 死锁演示
       */
      public class DeadDemo implements Runnable{
      
          private static Object object = new Object();
      
          @Override
          public void run() {
              //持有资源
              synchronized (object) {
                  System.out.println(Thread.currentThread().getName()+"占用资源");
                  Thread.currentThread().suspend();
              }
              System.out.println(Thread.currentThread().getName()+"释放资源");
          }
      
          public static void main(String[] args) throws InterruptedException {
              Thread thread = new Thread(new DeadDemo(),"对比线程");
              thread.start();
              Thread.sleep(1000L);
              thread.resume();
      
              Thread deadThread = new Thread(new DeadDemo(),"死锁线程");
              deadThread.start();
              deadThread.resume();
      
          }
      }
用法
  • wait()暂停执行、放弃已经获得的锁、进入等待状态

  • notify()随机唤醒一个处于等待锁的线程

  • notifyAll()唤醒所有处于等待锁的线程,自行抢占cpu资源

  • 例子

    package com.xdclass.thread.hang;
    
    public class WaitDemo implements Runnable {
    
      private static Object waitObj = new Object();
    
      @Override
      public void run() {
          //持有资源
          synchronized (waitObj) {
              System.out.println(Thread.currentThread().getName()+"占用资源");
              try {
                  waitObj.wait();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
          System.out.println(Thread.currentThread().getName()+"释放资源");
      }
    
      public static void main(String[] args) throws InterruptedException {
          Thread thread = new Thread(new WaitDemo(),"对比线程");
          thread.start();
    
          Thread thread2 = new Thread(new WaitDemo(),"对比线程2");
          thread2.start();
          Thread.sleep(3000L);
    
          synchronized (waitObj) {
              // 改成notifyAll()可一次唤醒所有wait状态的线程,notify()只能唤醒一次,而且是按照进入synchronized的顺序来地
              waitObj.notify();
              waitObj.notify();
          }
    
      }
    }

    结果是:

    对比线程占用资源
    对比线程2占用资源
    对比线程2释放资源
    对比线程释放资源

    可以看到notify每次只通知一个线程,如果想唤醒所有的,把两个notify()改成notifyAll()即可

什么时候适合使用挂起线程?

我等的船还没来(等待未确定的资源),我等的人还没来。直到通知方法被调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值