public class ReentrantReadWriteLockTest { private Map<String, String> map = new HashMap<>(); public static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); //获取读锁 private Lock readLock = readWriteLock.readLock(); //获取写锁 private Lock writeLock = readWriteLock.writeLock(); public static void main(String[] args) throws InterruptedException { //testReenter(); //testUpgrade(); //testDowngrade(); ReentrantReadWriteLockTest reentrantReadWriteLockTest = new ReentrantReadWriteLockTest(); //写操作测试 可以知道写操作是互斥的 Runnable runnable1 = () -> { for (int i = 0; i < 5; i++) { reentrantReadWriteLockTest.write("key" + i, "value"+i); } }; Thread t1 = new Thread(runnable1); Thread t2 = new Thread(runnable1); Thread t3 = new Thread(runnable1); t1.start(); t2.start(); t3.start(); t1.join(); t2.join(); t3.join(); System.out.println("开始并发读取。。。"); //读操作测试 可以知道读操作是可以并发执行的 Runnable runnable2 = () -> { for (int i = 0; i < 5; i++) { System.out.println(reentrantReadWriteLockTest.read("key" + i)); } }; new Thread(runnable2).start(); new Thread(runnable2).start(); new Thread(runnable2).start(); } /** * 在同一个线程中,在没有释放写锁的情况下,就去申请读锁,这属于锁降级,ReentrantReadWriteLock是支持的,不过锁的释放有问题,获取到锁就要释放锁 * 为什么有锁的降级,在一个线程进行写操作后, 当前线程可以继续读取数据,又不希望别的线程对数据更改,又可以让别的线程可以读取数据 */ public static void testDowngrade() { ReentrantReadWriteLock rtLock = new ReentrantReadWriteLock(); rtLock.writeLock().lock(); System.out.println("writeLock"); rtLock.readLock().lock(); System.out.println("get read lock"); } //在同一个线程中,在没有释放读锁的情况下,就去申请写锁,这属于锁升级,ReentrantReadWriteLock是不支持的。 public static void testUpgrade() { ReentrantReadWriteLock rtLock = new ReentrantReadWriteLock(); rtLock.readLock().lock(); System.out.println("get readLock."); // rtLock.readLock().unlock(); rtLock.writeLock().lock(); System.out.println("blocking"); rtLock.writeLock().unlock(); } //可重入锁,就是说一个线程在获取某个锁后,还可以继续获取该锁,即允许一个线程多次获取同一个锁,要注意的是获取多少次锁就要释放多少次锁,不然会发生死锁,例子讲的是两次获取写锁 public static void testReenter() throws InterruptedException { final ReentrantReadWriteLock lock = new ReentrantReadWriteLock (); Thread t = new Thread(new Runnable() { @Override public void run() { lock.writeLock().lock(); System.out.println("Thread real execute"); lock.writeLock().unlock(); } }); lock.writeLock().lock(); lock.writeLock().lock(); t.start(); Thread.sleep(200); System.out.println("realse one once"); lock.writeLock().unlock(); // lock.writeLock().unlock(); } /** * 写操作 * @param key * @param value */ public void write(String key, String value) { writeLock.lock(); System.out.println(Thread.currentThread().getName() + " 写操作正在执行。。。"); try { Thread.sleep(2000); map.put(key, value); } catch (Exception e) { e.printStackTrace(); } finally { writeLock.unlock(); } } /** * 读操作 * @param key * @return */ public String read(String key) { readLock.lock(); System.out.println(Thread.currentThread().getName() + " 读操作正在执行。。。"); try { Thread.sleep(2000); return map.get(key); } catch (Exception e) { e.printStackTrace(); } finally { readLock.unlock(); } return null; } }
原文地址:https://www.cnblogs.com/moris5013/p/11764153.html
时间: 2024-10-17 08:30:16