- 重入锁ReentrantLock,支持重进入的锁,能支持一个线程对资源的重复加锁
- 支持获取锁时的公平和非公平的选择,默认非公平
- 锁的公平与否:在绝对时间上,先对锁进行获取的请求一定先被满足,则锁是公平的,反之不公平。
- 重进入是指任意线程在获取到锁之后能够再次获取该锁,需要解决两个问题:
- 识别获取锁的线程是否为占据当前锁的线程。
- 线程重复n次获取锁,随后第n次释放锁后,其他线程能获取到锁。
- ReentrantLock通过组合自定义同步�器实现锁的获取和释放:
- nonfairTryAcquire方法非公平获取
- tryAcquire()方法公平获取,比nonfairTryAcquire多了hasQueuedPredecessors()方法判断同步队列当前节点是否有前驱节点的判断。 公平锁和非公平锁的代码示例:
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author pengjunzhe
*/
public class FairAndUnfairTest {
private static Lock fairLock = new ReentrantLock2(true);
private static Lock unFairLock = new ReentrantLock2(false);
@Test
public void fair() {
testLock(fairLock);
}
@Test
public void unfair() {
testLock(unFairLock);
}
private void testLock(Lock lock) {
//TODO:启动5个Job
for (int i = 0; i < 5; i ) {
Thread thread = new Thread(new Job(lock), String.valueOf(i));
thread.start();
}
SleepUtils.second(2);
}
private static class Job extends Thread {
private Lock lock;
public Job(Lock lock) {
this.lock = lock;
}
@Override
public void run() {
// TODO:连续两次打印当前的Thread和等待队列中的Thread
for (int i = 0; i < 2; i ) {
lock.lock();
try {
System.out.println("Lock by["
Thread.currentThread().getName()
"]"
"Waiting by " ((ReentrantLock2) lock).getQueuedThreadNames());
} finally {
lock.unlock();
}
}
}
}
private static class ReentrantLock2 extends ReentrantLock {
public ReentrantLock2(boolean fair) {
super(fair);
}
@Override
public Collection<Thread> getQueuedThreads() {
List<Thread> threads = new ArrayList<>(super.getQueuedThreads());
Collections.reverse(threads);
return threads;
}
public Collection<String> getQueuedThreadNames() {
List<String> names = new ArrayList<>(8);
getQueuedThreads().forEach((s) -> names.add(s.getName()));
return names;
}
}
}
输出分别为: Fair:
代码语言:javascript复制Lock by[0]Waiting by []
Lock by[1]Waiting by [2, 3, 4, 0]
Lock by[2]Waiting by [3, 4, 0, 1]
Lock by[3]Waiting by [4, 0, 1, 2]
Lock by[4]Waiting by [0, 1, 2, 3]
Lock by[0]Waiting by [1, 2, 3, 4]
Lock by[1]Waiting by [2, 3, 4]
Lock by[2]Waiting by [3, 4]
Lock by[3]Waiting by [4]
Lock by[4]Waiting by []
Unfair:
代码语言:javascript复制Lock by[0]Waiting by []
Lock by[0]Waiting by [1, 2, 3, 4]
Lock by[1]Waiting by [2, 3, 4]
Lock by[1]Waiting by [2, 3, 4]
Lock by[2]Waiting by [3, 4]
Lock by[2]Waiting by [3, 4]
Lock by[3]Waiting by [4]
Lock by[3]Waiting by [4]
Lock by[4]Waiting by []
Lock by[4]Waiting by []