赞
踩
ReadWriteLock 是 java.util.concurrent.locks 包下的一个接口,该接口允许一次读取多个线程,但一次只能写入一个线程
public interface ReadWriteLock
以下是 Lock 类中可用的重要方法列表
方法 | 描述 |
---|---|
public Lock readLock() | 返回用于读的锁 |
public Lock writeLock() | 返回用于写的锁 |
以下TestThread程序演示了ReadWriteLock接口的这些方法。这里我们使用readlock()获取读锁定和writeLock()来获取写锁定
package com.java.springtest.testdemo; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * @author Woo_home * @create by 2020/2/2 */ public class TestThread { // 开启公平锁 private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); // 定义消息属性 private static String message = ""; // 定义读锁 static class Reader implements Runnable { @Override public void run() { if (lock.isWriteLocked()) { System.out.println("Write Lock Present"); } lock.readLock().lock(); try { Long duration = (long) (Math.random() * 10000); System.out.println(Thread.currentThread().getName() + " Time Taken " + (duration / 1000) + " seconds"); Thread.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println(Thread.currentThread().getName() + ": " + message); lock.readLock().unlock(); } } } // 定义写锁 WriterA static class WriterA implements Runnable { @Override public void run() { lock.writeLock().lock(); try { Long duration = (long) (Math.random() * 10000); System.out.println(Thread.currentThread().getName() + " Time Taken " + (duration / 1000) + " second"); Thread.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } finally { message = message.concat("a"); lock.writeLock().unlock(); } } } // 定义写锁 WriterB static class WriterB implements Runnable { @Override public void run() { lock.writeLock().lock(); try { Long duration = (long) (Math.random() * 10000); System.out.println(Thread.currentThread().getName() + " Time Taken " + (duration / 1000) + " second"); Thread.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } finally { message = message.concat("b"); lock.writeLock().unlock(); } } } public static void main(String[] args) throws InterruptedException { // 启动线程 Thread thread1 = new Thread(new WriterA()); thread1.setName("Writer A"); Thread thread2 = new Thread(new WriterB()); thread2.setName("Writer B"); Thread thread3 = new Thread(new Reader()); thread3.setName("Reader"); thread1.start(); thread2.start(); thread3.start(); // 线程强制执行 thread1.join(); thread2.join(); thread3.join(); } }
输出:
定义一个资源类(未加读写锁前)
class MyCache { private volatile Map<String,Object> map = new HashMap<>(); public void put(String key,Object value) { System.out.println(Thread.currentThread().getName() + " 写入数据" + key); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } map.put(key,value); System.out.println(Thread.currentThread().getName() + " 写入完成"); } public void get(String key) { System.out.println(Thread.currentThread().getName() + " 读取数据"); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } Object result = map.get(key); System.out.println(Thread.currentThread().getName() + " 读取完成" + result); } }
测试类:
public class ReadWriteLockDemo { public static void main(String[] args) { MyCache myCache = new MyCache(); for (int i = 1; i <= 5; i++) { final int tempInt = i; new Thread(() -> { myCache.put(tempInt+"",tempInt+""); },String.valueOf(i)).start(); } for (int i = 1; i <= 5; i++) { final int tempInt = i; new Thread(() -> { myCache.get(tempInt+""); },String.valueOf(i)).start(); } } }
输出:
可以发现,当一个线程写入的时候,另外的线程也在写入,导致其它线程会读取不到数据,正确的例子应该是写入之后会有个写入完成再读取数据的
资源类(加读写锁后)
class MyCache { private volatile Map<String,Object> map = new HashMap<>(); private ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public void put(String key,Object value) { readWriteLock.writeLock().lock(); try { System.out.println(Thread.currentThread().getName() + " 写入数据" + key); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } map.put(key,value); System.out.println(Thread.currentThread().getName() + " 写入完成"); } catch (Exception e) { e.printStackTrace(); } finally { readWriteLock.writeLock().unlock(); } } public void get(String key) { readWriteLock.readLock().lock(); try { System.out.println(Thread.currentThread().getName() + " 读取数据"); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } Object result = map.get(key); System.out.println(Thread.currentThread().getName() + " 读取完成" + result); } catch (Exception e) { e.printStackTrace(); } finally { readWriteLock.readLock().unlock(); } } }
测试类
package juc; public class ReadWriteLockDemo { public static void main(String[] args) { MyCache myCache = new MyCache(); for (int i = 1; i <= 5; i++) { final int tempInt = i; new Thread(() -> { myCache.put(tempInt+"",tempInt+""); },String.valueOf(i)).start(); } for (int i = 1; i <= 5; i++) { final int tempInt = i; new Thread(() -> { myCache.get(tempInt+""); },String.valueOf(i)).start(); } } }
输出:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。