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 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{ } }
java 读写锁 高位 低位,java读写锁升级与降级、并会发现死锁。抛出异常
最新推荐文章于 2022-08-28 21:54:21 发布