公平锁
公平是针对锁的获取而言的,如果一个锁是公平的,那么锁的获取顺序就应该符合请求的绝对时间顺序。可以通过控制队列来实现一个公平锁,线程进入队列后,每次都唤醒队列中的第一个线程。
公平锁的实现
import java.util.ArrayList;
import java.util.List;
public class FairLock {
private boolean isLocked = false;
private Thread lockingThread = null;
private List<QueueObject> waitingThreads = new ArrayList<QueueObject>();
boolean isLockedForThisThread = true;
public void lock() throws InterruptedException {
QueueObject queueObject = new QueueObject();
synchronized (this) {
waitingThreads.add(queueObject);
}
// 可重入锁实现
while (isLockedForThisThread) {
synchronized (this) {
isLockedForThisThread = isLocked || waitingThreads.get(0) != queueObject;
if (!isLockedForThisThread) {
isLocked = true;
waitingThreads.remove(queueObject);
lockingThread = Thread.currentThread();
return;
}
}
try {
queueObject.doWait();
} catch (InterruptedException e) {
synchronized (this) {
waitingThreads.remove(queueObject);
}
throw e;
}
}
}
public synchronized void unlock() {
if (this.lockingThread != Thread.currentThread()) {
throw new IllegalMonitorStateException("Calling thread has not locked this lock");
}
isLocked = false;
lockingThread = null;
if (waitingThreads.size() > 0) {
// 将队列的第一个元素叫醒
waitingThreads.get(0).doNotify();
}
}
}
队列实现类
public class QueueObject {
private boolean isNotified = false;
public synchronized void doWait() throws InterruptedException {
// 只要没被叫醒就一直等待
while (!isNotified) {
this.wait();
}
this.isNotified = false;
}
public synchronized void doNotify() {
this.isNotified = true;
// 当前等待的就被叫醒
this.notify();
}
public boolean equals(Object o) {
return this == o;
}
}