JUC-Lock


顶层接口:

  • lock() // 如果锁可用就获得锁,如果锁不可用就阻塞直到锁释放
  • lockInterruptibly() // 和 lock()方法相似, 但阻塞的线程可中断,抛出 java.lang.InterruptedException异常
  • tryLock() // 非阻塞获取锁;尝试获取锁,如果成功返回true
  • newCondition()
  • unlock()

Condition:

为线程提供了等待、通知机制(wait、signal)

  1. 等待(Await):
    • 当一个线程持有相关的Lock但希望暂时释放锁,并等待某个条件变为真时,它可以调用Conditionawait()方法。这类似于Objectwait()方法。调用await()会使当前线程进入等待状态直到它被通知或被中断。
  2. 通知(Signal):
    • 另一个线程可以通过调用Condition的signal()或signalAll()方法来唤醒一个或所有等待的线程。这类似于Object的notify()或notifyAll()方法。调用signal()会唤醒一个等待在Condition上的线程,而signalAll()会唤醒所有等待的线程。

await():

将当前线程加入condition的等待队列

释放当前condition对应的锁

当前线程被挂起(阻塞)(使用LockSupport.park)

signal:

使用LockSupport.unpark,进行解锁

常见用法

1、生产者、消费者

一个锁,分两个condition

  • notFull
  • notEmpty

生产者等notFull

消费者等notEmpty

Q:为什么不用两个锁

A:

1、因为消费队列是同一个,用一个锁可以更好的保证共享数据的一致性

2、通知更加精确,不会通知到无关的线程

3、简化了代码逻辑

4、性能优化

5、避免信号丢失

常见实现

1、ReentrantLock

2、ReentrantReadWriteLock

3、StampedLock

参考:

1、https://zhuanlan.zhihu.com/p/492481897


文章作者: 王利康
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 王利康 !
  目录