基本锁
private boolean isLocked = false;
public synchronized void doLock() throws InterruptedException {
while (isLocked) {
wait();
}
isLocked = true;
}
public synchronized void dounlock() {
isLocked = false;
notifyAll();
}
}
重入锁
手写重入锁 对应Java ReentrantLock 类(非公平)
private volatile boolean isLocked = false;
private int lockNum = 0;
private Thread lockBy = null;
public synchronized void doLock() throws InterruptedException {
Thread curr = Thread.currentThread();
while (isLocked && curr != lockBy) {
wait();
}
isLocked = true;
lockNum++;
lockBy = curr;
}
public synchronized void dounlock() {
if(lockBy == Thread.currentThread()){
lockNum--;
}
if (lockNum == 0) {
isLocked = false;
notifyAll();
lockBy = null;
return;
}
}
读写锁
import java.util.HashMap;
import java.util.Map;
public class ReadWriteLock {
private Map<Thread, Integer> readmap = new HashMap<>();
private int writerAccess = 0;
private int requestWriter = 0;
private Thread writerThred = null;
public synchronized void lockRead() throws InterruptedException {
Thread callThred = Thread.currentThread();
while (!canGrantReadAccess(callThred)) {
wait();
}
readmap.put(callThred, getReadAccessCount(callThred) + 1);
}
public synchronized void unlockRead() {
Thread callThread = Thread.currentThread();
if (!isReader(callThread)) {
throw new IllegalMonitorStateException("IllegalMonitorStateException");
}
int acccessCount = getReadAccessCount(callThread);
if (acccessCount == 1) {
readmap.remove(callThread);
} else {
readmap.put(callThread, acccessCount - 1);
}
notifyAll();
}
public boolean canGrantReadAccess(Thread callThread) {
if (isWriter(callThread)) return true;
if (hasWriter()) return false;
if (isReader(callThread)) return true;
if (hasWriterRequest()) return false;
return true;
}
public boolean isWriter(Thread callThread) {
return this.writerThred == callThread;
}
public boolean isReader(Thread callThread) {
return readmap.containsKey(callThread);
}
public boolean hasWriter() {
return writerThred != null;
}
public boolean hasWriterRequest() {
return this.requestWriter > 0;
}
public int getReadAccessCount(Thread callThread) {
if (readmap.containsKey(callThread)) {
return readmap.get(callThread);
}
return 0;
}
public synchronized void lockwrite() throws InterruptedException {
Thread callThread = Thread.currentThread();
requestWriter++;
while (!canGrantWriteAccess(callThread)) {
wait();
}
requestWriter--;
writerAccess++;
writerThred = callThread;
}
public boolean canGrantWriteAccess(Thread callThread) {
if (isOnlyReader(callThread)) return true;
if (writerThred == null) return true;
if (hasReader()) return false;
if (!isWriter(callThread)) return false;
return true;
}
public boolean isOnlyReader(Thread callThread) {
if (readmap.size() == 1 && readmap.get(callThread) != null) {
return true;
}
return false;
}
private boolean hasReader() {
return readmap.size() > 0;
}
public synchronized void unlockwrite() {
if (!isWriter(Thread.currentThread())) {
throw new IllegalMonitorStateException("IllegalMonitorStateException");
}
writerAccess--;
if (writerAccess == 0) {
writerThred = null;
}
notifyAll();
}
}