Java多线程Day17-JUC锁基本概念

262 阅读4分钟

JUC锁基本概念

基本概念

  • 根据锁添加到Java中的时间 ,Java中的锁分为同步锁和JUC包中的锁JUC

同步锁

  • 通过synchronized关键字来进行同步,来实现对资源进行互斥访问的锁

  • 同步锁的原理:

    • 对于每一个对象有且仅有一个同步锁
    • 不同的线程都可以访问同步锁,但是在同一个时间点,有且只有一个线程可以获取到同步锁
    • 获取到同步锁的线程可以进行CPU调度,从而在CPU上执行线程
    • 没有获取到同步锁的线程必须进行等待,直到获取到同步锁之后才可以继续运行

JUC锁

在这里插入图片描述

  • JUC中的锁包括:

    • Lock接口

    • ReentrantLock独占锁

    • ReadWriteLock接口

    • ReentrantReadWriteLock读写锁

    • LockSupport阻塞原语

    • Condition条件

    • 三个抽象类:

      • AbstractOwnableSynchronizer
      • AbstractQueuedSynchronizer
      • AbstractQueuedLongSynchronizer
    • 其余包括CountDownLatch, CyclicBarrierSemaphore是通过AQS实现的

Lock

  • JUC包中的Lock接口支持语义不同的锁

  • 语义不同是指锁可以有公平机制的锁,非公平机制的锁,可重入的锁等

  • 公平机制的锁:

    • 不同线程获取锁的机制是公平的
  • 非公平机制的锁:

    • 不同线程获取锁的机制是非公平的
  • 可重入的锁:

    • 一个锁可以被一个线程多次获取

ReentrantLock

  • ReentrantLock是一个独占锁,同一个时间点只能被一个线程获取到

  • ReentrantLock锁包括公平的ReentrantLock和非公平的ReentrantLock:

    • 公平的ReentrantLock: 不同线程获取锁的机制是公平的
    • 非公平的ReentrantLock: 不同的线程获取锁的机制是非公平的
  • ReentrantLock是一个可重入的锁

  • ReentrantLockUML图:
    在这里插入图片描述

  • ReentrantLock实现了Lock接口

  • ReentrantLock中有一个Sync类型的成员变量sync

  • Sync是一个抽象类,继承自AQS

  • ReentrantLock中有公平锁类FairSync和非公平锁类NonfairSync. 都是Sync的子类

  • ReentrantLock默认是非公平锁

ReentrantReadWriteLock

  • ReentrantReadWriteLock是读写锁接口ReadWriteLock的实现类,包括子类ReadLockWriteLock

    • ReadLock是共享锁
    • WriteLock是独占锁
  • ReentrantReadWriteLockUML图:
    在这里插入图片描述

  • ReentrantReadWriteLock实现了ReadWriteLock接口

  • ReentrantReadWriteLock中包含Sync对象,读锁ReadLock和写锁WriteLock. 读锁ReadLock和写锁WriteLock都实现了Lock接口

  • ReentrantReadAndWriteLock中包含一个Sync类型的成员变量sync.Sync是一个抽象类,继承自AQS.Sync中也包含公平所FairSync和非公平锁NonfairSync

ReadWriteLock

  • ReadWriteLock接口定义了读取者共享而写入者独占的锁
  • JUC包中的ReentrantReadWriteLock实现类该接口
  • 可以自定义ReadWriteLock锁的实现

LockSupport

  • LockSupport提供了创建锁和其余同步类的基本线程阻塞原语
  • LockSupport的功能类似于线程Thread中的Thread.suspend()Thread.resume()
  • LockSupport中有park()unpark() 方法分别是阻塞进程和解除阻塞进程,但是不会遇到死锁的情况

Condition

  • Condition需要和Lock联合使用.作用是用来代替Object监视器方法,可以通过await() 来休眠和signal() 来唤醒线程
  • Condition接口中定义了与锁相关联的条件变量.这些变量的用法类似于Object访问的隐式监视器,但是功能更加强大
  • 一个Lock接口可能于多个Condition对象相关联

AbstractQueuedSynchronizer

  • AbstractQueuedSynchronizer就是AQS
  • 用来定义锁以及依赖于排队阻塞进程的其余的同步器
  • ReentrantLock, ReentrantReadWriteLock, CountDownLatch, CyclicBarrierSemaphore类都是基于AQS类实现的

AbstractQueuedLongSynchronizer

  • AbstractQueuedLongSynchronizer类功能和AbstractQueuedSynchronizer类似
  • AbstractQueuedLongSynchronizer提供了对64位的支持

AbstractOwnableSynchronizer

  • AbstractOwnableSynchronizer类用于记录当前保持独占的同步线程
  • AbstractQueuedSynchronizerAbstractQueuedLongSynchronizer都实现自AbstractOwnableSynchronizer

CountDownLatch

  • CountDownLatch是一个同步辅助类,在完成一组正在其余线程中执行的操作之前,允许一个或者多个线程一直等待
  • CountDownLatchUML图:
    在这里插入图片描述
  • CountDownLatch中包含了Sync类型的sync对象 .CountDownLatchSync的一个实例,继承自AQS

CyclicBarrier

  • CyclicBarrier是一个同步辅助类,允许一组线程相互等待,直到到达某个公共屏障点common barrier point

  • 因为barrier在释放等待线程后可以重用,所以称作循环barrier
    在这里插入图片描述

  • CyclicBarrier包含ReentrantLock类型的lockCondition类型的trip. 是通过独占锁实现的

  • CyclicBarrier和CountDownLatch的区别:

    • CyclicBarrier则是允许N个线程相互等待 ; CountDownLatch的作用是允许1个或者N个线程等待其余线程完成执行
    • CyclicBarrier的计数器可以被重置后使用,因此称作可循环的barrier; CountDownLatch的计数器无法被重置

Semaphore

  • Semaphore是一个计数信号量,本质是一个共享锁

  • 信号量中维护一个信号量许可集:

    • 线程可以通过调用acquire() 来获取信号量的许可
    • 当信号量中有可用的许可时,线程可以获取该许可; 否则线程必须等待,直到有可用的许可为止
    • 线程可以通过调用release() 来释放所持有的信号量许可
  • SemaphoreUML图:
    在这里插入图片描述

  • Semaphore包含Sync类型的sync对象

  • Sync继承自AQS抽象类,包括公平信号量FairSync和非公平信号量NonfairSync