Java读写锁
Java读写锁,ReadWriteLock.java接口, RentrantReadWriteLock.java实现。通过读写锁,可以实现读-读线程并发,读-写,写-读线程互斥进行。以前面试遇到一个问题,ConcurrentHashMap的实现原理,如何封装Map效率更高。今天看了《Java并发编程实战》,封装的ReadWriteMap类,效率就比ConcurrentHashMap效率更高,在读多写少的场景。
ReadWriteMap.java
public class ReadWriteMap<K, V> {
private final Map<K, V> map;
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final Lock readLock = readWriteLock.readLock();
private final Lock writeLock = readWriteLock.writeLock(); public ReadWriteMap(Map<K, V> map){
this.map = map;
} public V put(K key, V value){
writeLock.lock();
try{
return map.put(key, value);
} finally {
//释放锁,一定要写在finally里面
writeLock.unlock();
}
} public V get(K key){
readLock.lock();
try{
return map.get(key);
} finally {
readLock.unlock();
}
} }
ConcurrentHashMap里面的putVal()方法
/** Implementation for put and putIfAbsent */
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh;
if (tab == null || (n = tab.length) == 0)
tab = initTable();
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))
break; // no lock when adding to empty bin
}
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else {
V oldVal = null;
synchronized (f) {
if (tabAt(tab, i) == f) {
if (fh >= 0) {
binCount = 1;
for (Node<K,V> e = f;; ++binCount) {
K ek;
if (e.hash == hash &&
((ek = e.key) == key ||
(ek != null && key.equals(ek)))) {
oldVal = e.val;
if (!onlyIfAbsent)
e.val = value;
break;
}
Node<K,V> pred = e;
if ((e = e.next) == null) {
pred.next = new Node<K,V>(hash, key,
value, null);
break;
}
}
}
else if (f instanceof TreeBin) {
Node<K,V> p;
binCount = 2;
if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
value)) != null) {
oldVal = p.val;
if (!onlyIfAbsent)
p.val = value;
}
}
}
}
if (binCount != 0) {
if (binCount >= TREEIFY_THRESHOLD)
treeifyBin(tab, i);
if (oldVal != null)
return oldVal;
break;
}
}
}
addCount(1L, binCount);
return null;
}
使用的是synchronized进行同步,synchronized是独占锁,在读多写少的情况下效率不高,极端情况就是所有都是读线程,串行执行。
Java读写锁的更多相关文章
- Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析
Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...
- java 读写锁
http://tutorials.jenkov.com/java-concurrency/read-write-locks.html 翻译 读写锁比LOCK的实现更复杂,想象有一个应用程序能读和写一些 ...
- java 读写锁详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt124 在java多线程中,为了提高效率有些共享资源允许同时进行多个读的操作, ...
- java读写锁ReadWriteLock
package com.java.concurrent; import java.util.concurrent.locks.ReadWriteLock; import java.util.concu ...
- [图解Java]读写锁ReentrantReadWriteLock
图解ReentrantReadWriteLock 如果之前使用过读写锁, 那么可以直接看本篇文章. 如果之前未使用过, 那么请配合我的另一篇文章一起看:[源码分析]读写锁ReentrantReadWr ...
- Java 读写锁的实现
一. synchronized和ReentrantLock的对比 到现在,看到多线程中,锁定的方式有2种:synchronized和ReentrantLock.两种锁定方式各有优劣,下面简单对比 ...
- java读写锁实现数据同步访问
锁机制最大的改进之一就是ReadWriteLock接口和它的唯一实现类ReentrantReadWriteLock.这个类有两个锁,一个是读操作锁,另一个是写操作锁.使用读操作锁时可以允许多个线程同时 ...
- Java读写锁(ReentrantReadWriteLock)学习
什么是读写锁 平时,我们常见的synchronized和Reentrantlock基本上都是排他锁,这些锁在同一时刻只允许一个线程进行访问,哪怕是读操作.而读写锁是维护了一对锁(一个读锁和一个写锁), ...
- 轻松掌握java读写锁(ReentrantReadWriteLock)的实现原理
转载:https://blog.csdn.net/yanyan19880509/article/details/52435135 前言 前面介绍了java中排它锁,共享锁的底层实现机制,本篇再进一步, ...
随机推荐
- luoguP3224 [HNOI2012]永无乡
https://www.luogu.org/problemnew/show/P3224 考虑对每个岛维护一颗平衡树,用并查集维护连通性,启发式合并即可 这东西其实是一个大暴力,每次把节点少的平衡树合并 ...
- loj #6235. 区间素数个数
#6235. 区间素数个数 题目描述 求 1∼n 1\sim n1∼n 之间素数个数. 输入格式 一行一个数 n nn . 输出格式 一行一个数,表示答案. 样例 样例输入 10 样例输出 4 样例解 ...
- SQL 判断Null
字段 is null 这是多久没写SQL 了啊....................
- TX2 默认root用户启动
Jetpack3.1 修改方式 修改1 gedit /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf 修改后: 修改2 gedit /root/.pro ...
- Qt 学习之路 2(48):QSortFilterProxyModel
Qt 学习之路 2(48):QSortFilterProxyModel 豆子 2013年4月11日 Qt 学习之路 2 6条评论 从本章开始,我们将逐步了解有关自定义模型的相关内容.尽管前面我们曾经介 ...
- vim多行注释与删除
一.多行注释 1. 首先按esc进入命令行模式下,按下Ctrl + v,进入列(也叫区块)模式;2. 在行首使用上下键选择需要注释的多行;3. 按下键盘(大写)“I”键,进入插入模式:4. 然后输入注 ...
- P4320 道路相遇
[Luogu4320] 必经点数==圆方树上两点路径上圆点数 也就等于边数/2+1 没什么好说的 , 看代码 #include<cstdio> #include<iostream&g ...
- POJ_3696 The Luckiest number 【欧拉定理+同余式+对取模的理解】
一.题目 Chinese people think of '8' as the lucky digit. Bob also likes digit '8'. Moreover, Bob has his ...
- ZQUOJ 22854 (优先队列+剪枝)
题目:给出K , N , M : N为顶点数 , M为边数 : 求K个从1到N的不重复的最短边 , 可以来回的走: 分析:很自然的就可以想到用个优先队列广收下K次终点嘛 , 但是.0.0 爆了 ...
- 单个html使用axios调用接口传参
单个html页面使用axios调用接口传参(没有使用v-cli搭建框架,也没有使用qs等等) 1.使用 URLSearchParams的方法 var params = new URLSearchPar ...