Java读写锁的基本使用
JDK1.5以后,提供读写锁。这种锁支持多线程读操作不互斥,多线程读与写互斥,多线程写与写互斥,但读与读操作并不互斥。这样有助于性能的提高。
我们对数据的操作无非两种:“读”和“写”,试想一个这样的情景,当十个线程同时读取某个数据时,这个操作应不应该加同步。所以我们使用ReentrantReadWriteLockt它是一个解决单线程写和多线程读的理想方法。它采用类似于读写分离的思路设定了读锁和写锁。对于这两个锁的访问保证尽可能大的读并行和写互斥。另外,在一定的条件下写锁可以转换成读锁,而读锁却不能转换成写锁。
上代码:
import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantReadWriteLock; //资源类 class MyCache{ private Map<String,Object> map = new ConcurrentHashMap<>(); private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); //读写分离 //模拟写操作 void Write(String key, Object value){ readWriteLock.writeLock().lock(); try{ System.out.println(Thread.currentThread().getName() +" 正在写入..."+",值为:"+key); try { TimeUnit.SECONDS.sleep(2); }catch (Exception e){ e.printStackTrace(); } map.put(key,value); System.out.println(Thread.currentThread().getName() +" 写入完毕!"); }catch (Exception e){ e.printStackTrace(); }finally { readWriteLock.writeLock().unlock(); } } void Read(String key){ readWriteLock.readLock().lock(); try{ System.out.println(Thread.currentThread().getName() +" 正在读取..."); Object res = map.get(key); System.out.println(Thread.currentThread().getName()+" 读到的值为:"+res); }catch (Exception e){ e.printStackTrace(); }finally { readWriteLock.readLock().unlock(); } } } public class ReadAndWriteLockDemo { public static void main(String[] args) { MyCache cache = new MyCache(); //模拟五个线程写入值 for (int i = 1; i <= 5; i++) { final int tmp = i; new Thread(() -> { cache.Write(tmp + "", tmp + ""); }, "写线程" + i).start(); } try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+",我静静地看着它们...."); //模拟五个线程正在读 for (int i = 1; i <=5 ; i++) { final int tmp = i; new Thread(()->{ cache.Read(tmp+""); },"读线程"+ i).start(); } } }
上一篇:
IDEA上Java项目控制台中文乱码