0
点赞
收藏
分享

微信扫一扫

JUC中的LockSupport工具类的使用

西曲风 2021-09-28 阅读 34
日记本

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

  • 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在下篇介绍

举报

相关推荐

0 条评论