JUC中的LockSupport工具类的使用上篇

在多线程中,线程的等待和唤醒已知的有两种:

  • 1.使用object的wait方法让线程等待,然后使用object的notify方法唤醒线程
  • 2.使用juc包中Condition的await()方法让线程等待,使用signal()方法唤醒线程

使用Object类中的方法实现线程等待和唤醒

 public static void testWaitAndNotify() throws InterruptedException {
        new Thread(()-> {
            System.out.println(Thread.currentThread().getName() + "============>start");
            synchronized (lock) {
                System.out.println("lock===============>");
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("end lock=================>");
            }
        },"t1").start();

        TimeUnit.SECONDS.sleep(5);
        synchronized (lock) {
            lock.notify();
            System.out.println("notify======================>");
        }
    }

t1线程中调用 lock.wait()方法让t1线程等待,主线程中休眠5秒之后,调用 lock.notify()方法唤醒了t1线程,输出的结果中,两行结果相差5秒左右,程序正常退出。

如果notify方法在wait方法之前,会有什么效果

 public static void testWaitAndNotify1() throws InterruptedException {
        new Thread(()-> {
            System.out.println(Thread.currentThread().getName() + "============>start");

            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lock) {
                System.out.println("lock===============>");
                try {

                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("end lock=================>");
            }
        },"t1").start();

        TimeUnit.SECONDS.sleep(1);
        synchronized (lock) {
            lock.notify();
            System.out.println("notify======================>");
        }
    }

输出了上面2行之后,程序一直无法结束,t1线程调用wait()方法之后无法被唤醒了,从输出中可见, notify()方法在 wait()方法之前执行了,等待的线程无法被唤醒了。说明:唤醒方法在等待方法之前执行,线程无法被唤醒。
关于Object类中的用户线程等待和唤醒的方法,总结一下:

  • 1.wait()/notify()/notifyAll()方法都必须放在同步代码(必须在synchronized内部执行)中执行,需要先获取锁
  • 2.线程唤醒的方法(notify、notifyAll)需要在等待的方法(wait)之后执行,等待中的线程才可能会被唤醒,否则无法唤醒

使用Condition实现线程的等待和唤醒

 public static void testCondition() throws InterruptedException {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "==============> start");
            REENTRANT_LOCK.lock();
            try {
                System.out.println("==================== wait start");
                CONDITION.await();
                System.out.println("==================== wait end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                System.out.println("解锁==========>" + Thread.currentThread().getName());

                REENTRANT_LOCK.unlock();

            }

        }, "condition").start();

        TimeUnit.SECONDS.sleep(5);
        REENTRANT_LOCK.lock();
        try {
            CONDITION.signal();
        } finally {
            System.out.println("解锁==========>" + Thread.currentThread().getName());

            REENTRANT_LOCK.unlock();
        }
    }

关于Condition中方法使用总结:

  • 使用Condtion中的线程等待和唤醒方法之前,需要先获取锁。否者会报 IllegalMonitorStateException异常
  • signal()方法先于await()方法之前调用,线程无法被唤醒

Object和Condition的局限性

程等待和唤醒的方法能够执行的先决条件是:线程需要先获取锁
唤醒方法需要在等待方法之后调用,线程才能够被唤醒

LockSupport在下篇介绍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值