首页 > 技术文章 > LockSupport、wait()、notify()

xiaofengshan 2020-03-30 09:52 原文

LockSupport

名词解释

LockSupport是一个在JUC包里的线程阻塞工具类,所有的方法都是静态方法,主要用途是让线程在任意位置阻塞,广泛应用在AQS和各种JUC的锁中。

代码

public static void threadOne(){
        System.out.println("当前线程状态1:"+Thread.currentThread().getState()); //RUNNABLE
        LockSupport.park();
        System.out.println("当前线程状态3:"+Thread.currentThread().getState()); //RUNNABLE
    }

    public void demo(){
        Thread t1 = new Thread(LockSupportDemo::threadOne, "t1");
        t1.start();
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("当前线程状态2:"+t1.getState());//WAITING
        try {
            LockSupport.unpark(t1);
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("当前线程状态4:"+t1.getState());//TERMINATED
    }

WaitAndNotify

名词解释

  • Wait
    wait()方法是object类的方法,解决的问题是线程间的同步,该过程包含了同步锁的获取和释放,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify()方法才会重新激活调用者。

注意:线程调用notify()之后,只有该线程完全从 synchronized代码里面执行完毕后,monitor才会被释放,被唤醒线程才可以真正得到执行权。

  • notify
    notify()方法是object类的方法,notify仅唤醒一个线程并允许它去获得锁,notifyAll是唤醒所有等待这个对象的线程并允许它们去获得对象锁。

wait()和notify()方法都需要同一个对象锁进行调用,否则将不会生效。

代码

public static void downLoad(){
         //下载图片
         for (int i = 0; i < 20; i++) {
             try {
                 TimeUnit.MILLISECONDS.sleep(100);
                 System.out.println("开始下载图片:"+(i*5+5)+"%");
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }

         }
         System.out.println("-----图片下载完毕----");
        synchronized (object){
             //进行唤醒
             object.notify();
        }
         //下载附件
         for (int i = 0; i < 20; i++) {
             try {
                 TimeUnit.MILLISECONDS.sleep(100);
                 System.out.println("开始下载附件:"+(i*5+5)+"%");
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }

         }
         System.out.println("-----附件下载完毕----");
     }

     /**
      * @Description: 图片展示
      * @Author: zhuyang
      * @Date: 2022/1/10 11:09
      * @return: void
      **/
     public static void imgShow(){
         synchronized (object){
              try {
                  object.wait();
                  System.out.println("-----进行图片展示----");
                  System.out.println("-----图片展示完毕----");
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
         }
     }

     public void demo() throws InterruptedException {
         Thread t1 = new Thread(WaitAndNotify::downLoad, "t1");
         Thread t2 = new Thread(WaitAndNotify::imgShow, "t2");
         t1.start();
         t2.start();
         t1.join();

     }

LockSupport与wait()和notify()区别

①: wait和notify都是Object中的方法,在调用这两个方法前必须先获得锁对象,但是park不需要获取某个对象的锁就可以锁住线程。
②: notify只能随机选择一个线程唤醒,无法唤醒指定的线程,unpark却可以唤醒一个指定的线程。

Gitee地址

https://gitee.com/zhuayng/foundation-study/tree/develop/JavaBasis/JUC/src/main/java/com/yxkj/juc/c_000

推荐阅读