JDK的Locks包提供了一系列锁和相关同步工具的实现,用于更灵活和精细地控制多线程中的并发访问。
Locks包中的Lock接口是最核心的接口之一,它提供了比synchronized关键字更为丰富的功能,允许以块结构或者非块结构的方式使用锁。Lock接口有六个主要的方法,包括lock()、unlock()、tryLock()等,它们为程序员提供了更多的控制权。ReentrantLock是Lock接口的一个典型实现,它不仅拥有Lock接口的所有功能,还增加了可重入的特性。
抽象类与接口
AbstractOwnableSynchronizer
这是一个抽象类,提供了锁的拥有者信息。它主要是为了创建具有所有权功能的同步器,例如信号量和事件计数。
类方法信息:
protected final void setExclusiveOwnerThread(Thread thread)
:这是一个受保护的方法,用于设置当前拥有独占访问权限的线程。传入一个线程对象作为参数,如果传入 null
,则表示没有线程拥有访问权限。
protected final Thread getExclusiveOwnerThread()
:这是一个受保护的方法,用于获取当前拥有独占访问权限的线程。如果没有线程拥有访问权限,返回 null
。
AbstractQueuedLongSynchronizer
这是一个为一系列所设计的抽象框架,比如信号量、事件等,其中操作长整型值。它提供了一个基于FIFO的阻塞队列,可以用于构建锁定和相关的同步器。
类方法信息:
tryAcquire(long)
: 尝试获取独占锁,如果成功则返回true,否则返回false。getFirstQueuedThread()
: 获取等待队列中的第一个线程。addWaiter(Node)
: 将一个节点添加到等待队列的尾部。setHead(Node)
: 设置等待队列的头部为指定的节点。doAcquireNanos(long, long)
: 在指定的时间内尝试获取独占锁,如果成功则返回true,否则返回false。isOnSyncQueue(Node)
: 判断指定的节点是否在同步队列上。compareAndSetTail(Node, Node)
: 原子地比较并设置等待队列的尾部节点。selfInterrupt()
: 中断当前线程。transferAfterCancelledWait(Node)
: 在取消等待后尝试将节点转移到同步队列。isHeldExclusively()
: 判断当前线程是否持有独占锁。getExclusiveQueuedThreads()
: 获取所有正在等待独占锁的线程集合。doAcquireShared(long)
: 尝试获取共享锁。acquireShared(long)
: 以共享模式获取锁。setState(long)
: 设置同步状态的值。apparentlyFirstQueuedIsExclusive()
: 判断等待队列中的第一个线程是否应该被视为独占线程。hasContended()
: 判断是否有线程争用锁。getQueueLength()
: 获取等待队列的长度。fullGetFirstQueuedThread()
: 获取等待队列中的第一个线程,包括那些因为调用了park
而被阻塞的线程。doAcquireSharedInterruptibly(long)
: 以可中断的方式尝试获取共享锁。hasQueuedThreads()
: 判断是否有线程在等待队列中。tryRelease(long)
: 尝试释放独占锁,如果成功则返回true,否则返回false。compareAndSetState(long, long)
: 原子地比较并设置同步状态的值。owns(ConditionObject)
: 判断当前线程是否拥有指定的条件对象的监视器。compareAndSetNext(Node, Node, Node)
: 原子地比较并设置节点的下一个节点。transferForSignal(Node)
: 将节点从等待队列转移到同步队列,以便唤醒后续等待的线程。hasWaiters(ConditionObject)
: 判断是否有线程在指定的条件对象上等待。acquireQueued(Node, long)
: 尝试获取队列中的节点所持有的锁。tryReleaseShared(long)
: 尝试释放共享锁,如果成功则返回true,否则返回false。getSharedQueuedThreads()
: 获取所有正在等待共享锁的线程集合。compareAndSetWaitStatus(Node, int, int)
: 原子地比较并设置节点的等待状态。getState()
: 获取同步状态的值。acquireInterruptibly(long)
: 以可中断的方式获取锁。cancelAcquire(Node?)
: 取消对指定节点的获取操作。hasQueuedPredecessors()
: 判断当前线程之前是否有其他线程在等待队列中。shouldParkAfterFailedAcquire(Node, Node)
: 在获取锁失败后,判断是否应该挂起当前线程。doAcquireInterruptibly(long)
: 以可中断的方式尝试获取独占锁。tryAcquireShared(long)
: 尝试获取共享锁,返回剩余可用资源的数量。setHeadAndPropagate(Node, long)
: 设置等待队列的头部为指定的节点,并传播其状态。isQueued(Thread)
: 判断指定的线程是否在等待队列中。getQueuedThreads()
: 获取等待队列中的所有线程。fullyRelease(Node)
: 完全释放节点所持有的锁,并返回释放前的状态值。acquire(long)
: 获取锁。toString()
: 返回同步器的字符串表示形式。parkAndCheckInterrupt()
: 挂起当前线程,并在唤醒时检查中断状态。doReleaseShared()
: 释放共享锁。getWaitQueueLength(ConditionObject)
: 获取指定条件对象的等待队列长度。tryAcquireSharedNanos(long, long)
: 在指定的时间内尝试获取共享锁,返回剩余可用资源的数量。releaseShared(long)
: 释放共享锁,如果成功则返回true,否则返回false。release(long)
: 释放独占锁,如果成功则返回true,否则返回false。compareAndSetHead(Node)
: 原子地比较并设置等待队列的头部节点。unparkSuccessor(Node)
: 唤醒等待队列中指定节点的后续节点。tryAcquireNanos(long, long)
: 在指定的时间内尝试获取独占锁,如果成功则返回true,否则返回false。findNodeFromTail(Node?)
: 从等待队列的尾部开始查找指定的节点。getWaitingThreads(ConditionObject)
: 获取指定条件对象上等待的所有线程集合。doAcquireSharedNanos(long, long)
: 在指定的时间内尝试获取共享锁。acquireSharedInterruptibly(long)
: 以可中断的方式获取共享锁。enq(Node)
: 将一个节点添加到等待队列的尾部,并返回添加后的节点。
AbstractQueuedSynchronizer
类似于AbstractQueuedLongSynchronizer,但主要面向简单的整数状态。这个类是构造锁和相关同步器的基石,比如信号量和事件。
类方法信息如下:
tryAcquire(int)
: 尝试获取独占锁,如果成功则返回true,否则返回false。enq(Node)
: 将节点添加到等待队列的尾部,并返回添加后的节点。acquire(int)
: 获取独占锁,可能会阻塞直到成功。hasWaiters(ConditionObject)
: 判断指定条件对象是否有线程在等待。releaseShared(int)
: 释放共享锁,如果成功则返回true,否则返回false。hasContended()
: 判断是否有线程争用锁。findNodeFromTail(Node?)
: 从等待队列的尾部开始查找指定的节点。release(int)
: 释放独占锁,如果成功则返回true,否则返回false。fullGetFirstQueuedThread()
: 获取等待队列中的第一个线程,包括那些因为调用了park
而被阻塞的线程。compareAndSetHead(Node)
: 原子地比较并设置等待队列的头部节点。acquireShared(int)
: 获取共享锁,可能会阻塞直到成功。shouldParkAfterFailedAcquire(Node, Node)
: 在获取锁失败后,判断是否应该挂起当前线程。apparentlyFirstQueuedIsExclusive()
: 判断等待队列中的第一个线程是否拥有独占锁。doReleaseShared()
: 释放共享锁。tryRelease(int)
: 尝试释放独占锁,如果成功则返回true,否则返回false。compareAndSetWaitStatus(Node, int, int)
: 原子地比较并设置节点的等待状态。compareAndSetNext(Node, Node, Node)
: 原子地比较并设置节点的下一个节点。getWaitQueueLength(ConditionObject)
: 获取指定条件对象的等待队列长度。getFirstQueuedThread()
: 获取等待队列中的第一个线程。doAcquireSharedNanos(int, long)
: 在指定的时间内尝试获取共享锁。transferForSignal(Node)
: 唤醒等待队列中指定节点的后续节点。tryAcquireNanos(int, long)
: 在指定的时间内尝试获取独占锁。addWaiter(Node)
: 将节点添加到等待队列的尾部。getWaitingThreads(ConditionObject)
: 获取指定条件对象上等待的所有线程集合。cancelAcquire(Node?)
: 取消对指定节点的获取操作。doAcquireNanos(int, long)
: 在指定的时间内尝试获取独占锁。isHeldExclusively()
: 判断当前线程是否拥有独占锁。doAcquireInterruptibly(int)
: 以可中断的方式获取独占锁。hasQueuedThreads()
: 判断是否有线程在等待队列中。tryAcquireShared(int)
: 尝试获取共享锁,返回剩余可用资源的数量。hasQueuedPredecessors()
: 判断当前线程之前是否有其他线程在等待队列中。isQueued(Thread)
: 判断指定的线程是否在等待队列中。setHead(Node)
: 设置等待队列的头部节点。tryReleaseShared(int)
: 尝试释放共享锁,如果成功则返回true,否则返回false。fullyRelease(Node)
: 完全释放节点所持有的锁,并返回释放前的状态值。acquireQueued(Node, int)
: 获取等待队列中的独占锁,可能会阻塞直到成功。doAcquireShared(int)
: 获取共享锁,可能会阻塞直到成功。getQueueLength()
: 获取等待队列的长度。getExclusiveQueuedThreads()
: 获取所有拥有独占锁的线程集合。doAcquireSharedInterruptibly(int)
: 以可中断的方式获取共享锁。acquireInterruptibly(int)
: 以可中断的方式获取独占锁。setState(int)
: 设置同步器的状态值。setHeadAndPropagate(Node, int)
: 设置等待队列的头部节点,并传播状态值。compareAndSetState(int, int)
: 原子地比较并设置同步器的状态值。toString()
: 返回同步器的字符串表示形式。transferAfterCancelledWait(Node)
: 在取消等待后,尝试转移节点到同步队列。compareAndSetTail(Node, Node)
: 原子地比较并设置等待队列的尾部节点。owns(ConditionObject)
: 判断当前线程是否拥有指定条件的监视器锁。isOnSyncQueue(Node)
: 判断节点是否在同步队列上。acquireSharedInterruptibly(int)
: 以可中断的方式获取共享锁。getSharedQueuedThreads()
: 获取所有拥有共享锁的线程集合。getState()
: 获取同步器的状态值。selfInterrupt()
: 自我中断当前线程。parkAndCheckInterrupt()
: 挂起当前线程并检查中断状态。unparkSuccessor(Node)
: 唤醒等待队列中指定节点的后续节点。tryAcquireSharedNanos(int, long)
: 在指定的时间内尝试获取共享锁。getQueuedThreads()
: 获取等待队列中的所有线程集合。
Condition
这是一个接口,它与Lock接口配合使用,使线程能够等待某个特定条件的发生。Condition接口允许更精细的线程同步控制。
- signalAll(): 唤醒所有等待在该Condition上的线程。
- awaitNanos(long): 使当前线程等待指定的纳秒数,或者直到其他线程调用signal()或signalAll()。返回值是实际等待的时间(可能小于请求的时间)。
- await(): 使当前线程等待,直到其他线程调用signal()或signalAll()。
- awaitUninterruptibly(): 使当前线程等待,直到其他线程调用signal()或signalAll(),忽略中断。
- await(long, TimeUnit): 使当前线程等待指定的时间量,或者直到其他线程调用signal()或signalAll()。返回值表示是否超时。
- signal(): 唤醒一个等待在该Condition上的线程。
- awaitUntil(Date): 使当前线程等待直到指定的日期,或者直到其他线程调用signal()或signalAll()。返回值表示是否超时。
Lock
这是一个接口,提供比synchronized关键字更灵活的锁定操作。Lock接口有不同的实现,如ReentrantLock,它允许更复杂的锁定操作,包括尝试获取锁,定时锁等。
类方法如下:
- tryLock(): 尝试获取锁,如果锁可用则立即返回true,否则返回false。
- unlock(): 释放锁。
- tryLock(long, TimeUnit): 尝试在给定的时间内获取锁,如果在指定时间内成功获取到锁,则返回true,否则返回false。
- newCondition(): 创建并返回与此锁关联的条件对象。
- lock(): 获取锁,如果锁不可用,则当前线程将被阻塞直到锁被释放。
- lockInterruptibly(): 获取锁,如果锁不可用,则当前线程将被阻塞直到锁被释放或者线程被中断。
ReadWriteLock
这是一个接口,管理一对关联的锁,一个用于读,一个用于写。它允许多个线程进行读,但只有一个线程进行写。
类方法如下:
readLock(): 这个方法返回一个用于读取操作的锁对象。当一个线程调用此方法获取读锁后,它可以访问共享资源,但其他线程仍然可以获取读锁或写锁。这意味着多个线程可以同时进行读取操作,只要没有线程持有写锁。
writeLock(): 这个方法返回一个用于写入操作的锁对象。当一个线程调用此方法获取写锁后,它将独占地访问共享资源,直到释放写锁。在此期间,其他线程不能获取读锁或写锁,以确保数据的一致性和完整性。