返回
北大青鸟长沙麓谷校区
置顶
该校与厚学网暂未合作,平台不保证课程的真实有效性,如有侵权等争议,请及时与厚学网联系处理

实现Java锁的两种机制

14 2022-07-18 09:14:41

学习笔记

java多线程编程环境下并发是常见问题,这两天看了锁相关的问题,记录下两个简单的用锁实现等待/唤醒机制的demo。

1.synchronized方式实现等待/唤醒。

public class WaitAndNotify {    private static boolean flag = true;    private static Object lock = new Object();    public static void main(String[] args) {
       Thread waitThread = new Thread(new Wait(), "WaitThread");
       waitThread.start();        try {
           TimeUnit.SECONDS.sleep(1);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       Thread notifyThread = new Thread(new Notify(), "NotifyThread");
       notifyThread.start();
   }    private static class Wait implements Runnable {        @Override
       public void run() {            synchronized (lock) {                while (flag) {
                   System.out.println(Thread.currentThread() + " flag是true,wait。。" + new SimpleDateFormat("HH:mm:ss").format(new Date()));                    try {
                       lock.wait();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
               System.out.println(Thread.currentThread() + " flag是false,开始继续工作" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
           }
       }
   }    private static class Notify implements Runnable {        @Override
       public void run() {            synchronized (lock){
               System.out.println(Thread.currentThread() + " 持有锁,发出通知" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
               lock.notifyAll();
               flag = false;                try {
                   TimeUnit.SECONDS.sleep(5);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
       }
   }
}

打印结果:

Thread[WaitThread,5,main] flag是true,wait。。18:55:28Thread[NotifyThread,5,main] 持有锁,发出通知18:55:29Thread[WaitThread,5,main] flag是false,开始继续工作18:55:34

分析:根据程序可以看到,大致的过程就是:WaitThread拿到lock对象的锁,然后根据flag标记,自己调用了wait()方法,从而释放锁并进入WAITTING状态。NotifyThread此时获取了lock对象的锁,然后进行notify操作,此时WaitThread被唤醒,但是,它不能立刻执行,因为唤醒线程NotifyThread还持有“该对象的同步锁”。必须等到NotifyThread线程释放了“对象的同步锁”之后,也就是同步代码块执行完以后,即睡眠5秒以后,等待线程WaitThread才能获取到“对象的同步锁”进而继续运行。

2.ReentrantLock方式实现等待/唤醒。

public class ReenterLockCondition {    private static ReentrantLock lock = new ReentrantLock();    private static Condition condition = lock.newCondition();    private static Runnable runnable = () -> {        try {            lock.lock();
           System.out.println(Thread.currentThread().getName() + "进入等待。。");
           condition.await();
           System.out.println(Thread.currentThread().getName() + "继续执行");
       } catch (InterruptedException e) {
           e.printStackTrace();
       } finally {            lock.unlock();
       }
   };    public static void main(String[] args) throws InterruptedException {
       Thread thread = new Thread(runnable, "thread--1");
       thread.start();
       Thread.sleep(2000);        lock.lock();
       condition.signal();
       System.out.println("主线程发出信号");        lock.unlock();
   }
}

打印结果:

thread--1进入等待。。主线程发出信号
thread--1继续执行


文中图片素材来源网络,如有侵权请联系删除
来源:北大青鸟长沙麓谷校区
热门课程 全部课程

热门动态

申请免费试听

只要一个电话

我们为您免费回电

立即申请
刷新
图形验证
关闭
>>
拖动左边滑块完成上方拼图