简介
ReentrantLock
由线程拥有 ,最后成功锁定,但尚未解锁。 调用lock
的线程将返回,成功获取锁,当锁不是由另一个线程拥有。 如果当前线程已经拥有该锁,该方法将立即返回。 这可以使用方法isHeldByCurrentThread()
和getHoldCount()
进行检查。
该类的构造函数接受可选的公平参数。 当设置true
,在争用下,锁有利于授予访问最长等待的线程。 否则,该锁不保证任何特定的访问顺序。 使用许多线程访问的公平锁的程序可能会比使用默认设置的整体吞吐量(即,更慢,通常要慢得多),但是具有更小的差异来获得锁定并保证缺乏饥饿。 但是请注意,锁的公平性不能保证线程调度的公平性。 因此,使用公平锁的许多线程之一可以连续获得多次,而其他活动线程不进行而不是当前持有锁。 另请注意, 未定义的tryLock()
方法不符合公平性设置。 如果锁可用,即使其他线程正在等待,它也会成功。
class X {
//实例化锁
private final ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
//获得锁
lock.lock();
// block until condition holds
try {
// ... method body
} finally {
//解锁
lock.unlock()
}
}
}
除了实现Lock
接口,这个类定义了许多public
种protected
方法用于检查锁的状态。 其中一些方法仅适用于仪器和监控。
此类的序列化与内置锁的操作方式相同:反序列化锁处于未锁定状态,无论其序列化时的状态如何。
此锁最多支持同一个线程的2147483647递归锁。 尝试超过此限制会导致Error
从锁定方法中抛出。
构造方法
构造方法与描述 |
---|
ReentrantLock() 创建一个 |
ReentrantLock(boolean fair) 根据给定的公平政策创建一个 |
方法
修饰语和类型 | 方法和描述 |
---|---|
int | getHoldCount() 查询当前线程对此锁的暂停数量。 |
protected Thread | getOwner() 返回当前拥有此锁的线程,如果不拥有,则返回 |
protected Collection<Thread> | getQueuedThreads() 返回包含可能正在等待获取此锁的线程的集合。 |
int | getQueueLength() 返回等待获取此锁的线程数的估计。 |
protected Collection<Thread> | getWaitingThreads(Condition condition) 返回包含可能在与此锁相关联的给定条件下等待的线程的集合。 |
int | getWaitQueueLength(Condition condition) 返回与此锁相关联的给定条件等待的线程数的估计。 |
boolean | hasQueuedThread(Thread thread) 查询给定线程是否等待获取此锁。 |
boolean | hasQueuedThreads() 查询是否有线程正在等待获取此锁。 |
boolean | hasWaiters(Condition condition) 查询任何线程是否等待与此锁相关联的给定条件。 |
boolean | isFair() 如果此锁的公平设置为true,则返回 |
boolean | isHeldByCurrentThread() 查询此锁是否由当前线程持有。 |
boolean | isLocked() 查询此锁是否由任何线程持有。 |
void | lock() 获得锁。 |
void | lockInterruptibly() 获取锁定,除非当前线程是 interrupted 。 |
Condition | newCondition() |
String | toString() 返回一个标识此锁的字符串以及其锁定状态。 |
boolean | tryLock() 只有在调用时它不被另一个线程占用才能获取锁。 |
boolean | tryLock(long timeout, TimeUnit unit) 如果在给定的等待时间内没有被另一个线程 占用 ,并且当前线程尚未被 保留,则获取该锁( interrupted) 。 |
void | unlock() 尝试释放此锁。 |
例如
package com.test;
import java.util.concurrent.locks.ReentrantLock;
class Movie implements Runnable{
private ReentrantLock lock = new ReentrantLock();
private int tickets = 200;
@Override
public void run() {
while (true) {
lock.lock(); // 获取锁
try {
if (tickets > 0) {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " " + tickets--);
} else {
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 释放所
}
}
}
}
public class Main5 {
public static void main(String[] args) {
Movie movie = new Movie();
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(movie);
thread.setName("thread" + i);
thread.start();
}
}
}