java读写锁升级与降级、并会发现死锁。抛出异常

package com.huawei.test;

import java.util.HashMap;
import java.util.Map;


public class SpinReadWriteLock {
private volatile Thread writeThread = null;
private volatile int writeCount = 0;
//标记已经获取读lock的线程想要获取写lock   但被阻止了(因各种原因)
private volatile Thread readRequestWriteLockingThread = null;
private volatile Map<Thread, Integer> readThread = new HashMap<>();
private Object read = new Object();

public void readLock() throws InterruptedException {
Thread current = Thread.currentThread();
synchronized (read) {
while (writeThread != null && writeThread != current) {
read.wait();
}
Integer readCount = readThread.get(current);
if (readCount == null) {
// 表示当前线程正在持有锁 对锁持有的次数+1
readCount = 0;
}
readCount++;
readThread.put(current, readCount);
}
}

public void readUnlock() {
synchronized (read) {
Thread current = Thread.currentThread();
Integer readCount = readThread.get(current);
if (readCount <= 1) {
readThread.remove(current);
read.notifyAll();
return;
}
readCount--;
readThread.put(current, readCount);
}
}

public void writeLock() throws InterruptedException, DeadLockException {

Thread current = Thread.currentThread();
synchronized (read) {
while ((writeThread != null && writeThread != current)
//写锁被别的线程持有
|| readThread.size() > 1
//或者有多余一个的读锁持者
|| (readThread.size()==1 && !readThread.containsKey(current))
//或者有一个读锁持有者   但不是自己
) {
if(readRequestWriteLockingThread != null && readRequestWriteLockingThread != current)
throw new DeadLockException();
readRequestWriteLockingThread = current;
read.wait();
}
writeThread = current;
writeCount++;
}
}

public void writeUnLock() {

Thread current = Thread.currentThread();
if(current != writeThread)
//
return ;
if (writeCount == 1) {

synchronized (read) {
writeCount = 0;
writeThread = null;
read.notifyAll();
return;
}
}
writeCount--;
}

public static void main(String[] args) {

for (int i = 0; i < 10; i++) {

// new Thread(new Read()).start();
// new Thread(new Write()).start();
new Thread(new DeadReadWrite()).start();
}
}

public final static SpinReadWriteLock READ_WRITE_LOCK = new SpinReadWriteLock();
public static class Read implements Runnable{

@Override
public void run() {

try {

READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");
Thread.sleep(100);

} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + "获取到了放弃读锁");
READ_WRITE_LOCK.readUnlock();
}

}
}
public static class Write implements Runnable{

@Override
public void run() {

try {
System.out.println(Thread.currentThread().getName() + "准备获取写锁");
READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");
Thread.sleep(200);

} catch (InterruptedException | DeadLockException e) {
System.out.println(Thread.currentThread().getName() + e.getLocalizedMessage());
} finally {
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();
}

}
}
public static class ReadWrite implements Runnable{

@Override
public void run() {


try {

READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");
Thread.sleep(20);
READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");
Thread.sleep(20);
READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");
Thread.sleep(20);
READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");
Thread.sleep(20);
READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");
Thread.sleep(20);
READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");
Thread.sleep(20);

} catch (InterruptedException | DeadLockException e) {
System.out.println(Thread.currentThread().getName() + e.getLocalizedMessage());
} finally {
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();
System.out.println(Thread.currentThread().getName() + "准备放弃读锁");
READ_WRITE_LOCK.readUnlock();
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();
System.out.println(Thread.currentThread().getName() + "准备放弃读锁");
READ_WRITE_LOCK.readUnlock();
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();
System.out.println(Thread.currentThread().getName() + "准备放弃读锁");
READ_WRITE_LOCK.readUnlock();
}

}
}

public static class DeadReadWrite implements Runnable{

@Override
public void run() {
try {

READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");
Thread.sleep(200);
READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");

} catch (InterruptedException | DeadLockException e) {
StackTraceElement[] ee = e.getStackTrace();
System.out.println(Thread.currentThread().getName() +"抛出异常");
for (StackTraceElement stackTraceElement : ee) {
System.out.println(stackTraceElement.toString());
}

} finally {
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();
System.out.println(Thread.currentThread().getName() + "准备放弃读锁");
READ_WRITE_LOCK.readUnlock();
}

}
}
public static class UnDeadReadWrite implements Runnable{

@Override
public void run() {
try {


READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");
Thread.sleep(200);
READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");


} catch (InterruptedException | DeadLockException e) {
System.out.println(Thread.currentThread().getName() + e.getLocalizedMessage());
} finally {
System.out.println(Thread.currentThread().getName() + "准备放弃读锁");
READ_WRITE_LOCK.readUnlock();
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();

}

}
}

public static class DeadLockException extends Exception{


}
}

猜你喜欢

转载自1064319393.iteye.com/blog/2389247
今日推荐