读写锁ReadWriteLock
lock锁,只允许一个进程进行读/写
使用ReadWriteLock读写锁,可以实现控制:
- 多个线程同时读
- 同一时间只允许一个线程写
下面的demo展示的是,当多个线程要进行同时写操作时,没有加锁的情况,会导致多个线程并发写:
运行结果:
代码:
/** * @author zkw * @Description 读写锁 */ public class ReadWriteLockDemo { public static void main(String[] args) { MyMap map = new MyMap(); for (int i = 0; i < 6; i++) { new Thread(()->{ try { map.put(Thread.currentThread().getName(),""); } catch (InterruptedException e) { e.printStackTrace(); } },i+"").start(); } for (int i = 0; i < 6; i++) { new Thread(()->{ try { map.get(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } },i+"").start(); } } } class MyMap{ private HashMap<String,String> map = new HashMap<>(); public void put(String key,String value) throws InterruptedException { System.out.println(Thread.currentThread().getName()+"开始写入"); TimeUnit.SECONDS.sleep(1); map.put(key, value); System.out.println(Thread.currentThread().getName()+"写入完成"); } public String get(String key) throws InterruptedException { System.out.println(Thread.currentThread().getName()+"开始读取"); TimeUnit.SECONDS.sleep(1); String s = map.get(key); System.out.println(Thread.currentThread().getName()+"读取完成"); return s; } }
下面使用ReadWriteLock锁对上面的demo进行优化,禁止多个线程同时读的情况,并允许多个线程同时写:
运行结果:
代码:
/** * @author zkw * @Description 读写锁 */ public class ReadWriteLockDemo { public static void main(String[] args) { MyMap map = new MyMap(); for (int i = 0; i < 6; i++) { new Thread(()->{ try { map.put(Thread.currentThread().getName(),""); } catch (InterruptedException e) { e.printStackTrace(); } },i+"").start(); } for (int i = 0; i < 6; i++) { new Thread(()->{ try { map.get(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } },i+"").start(); } } } class MyMap{ private HashMap<String,String> map = new HashMap<>(); ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); //创建读写锁 public void put(String key,String value) throws InterruptedException { readWriteLock.writeLock().lock(); //写锁 System.out.println(Thread.currentThread().getName()+"开始写入"); TimeUnit.SECONDS.sleep(1); map.put(key, value); System.out.println(Thread.currentThread().getName()+"写入完成"); readWriteLock.writeLock().unlock(); } public String get(String key) throws InterruptedException { readWriteLock.readLock().lock(); //读锁 System.out.println(Thread.currentThread().getName()+"开始读取"); TimeUnit.SECONDS.sleep(1); String s = map.get(key); System.out.println(Thread.currentThread().getName()+"读取完成"); readWriteLock.readLock().unlock(); return s; } }