ReadWriteLock如何使用?

ReadWriteLock,读写锁。
ReentrantReadWriteLock 是 ReadWriteLock 的一种实现。

特点:

  • 包含一个 ReadLock 和 一个 WriteLock 对象
  • 读锁与读锁不互斥;读锁与写锁,写锁与写锁互斥
  • 适合对共享资源有读和写操作,写操作很少,读操作频繁的场景
  • 可以从写锁降级到读锁。获取写锁->获取读锁->释放写锁
  • 无法从读锁升级到写锁
  • 读写锁支持中断
  • 写锁支持Condition;读锁不支持Condition

示例1–根据 key 获取 value 值

private ReadWriteLock lock = new ReentrantReadWriteLock();//定义读写锁 //根据 key 获取 value 值public Object getValue(String key){//使用读写锁的基本结构lock.readLock().lock();//加读锁Object value = null;try{value = cache.get(key);if(value == null){lock.readLock().unlock();//value值为空,释放读锁lock.writeLock().lock();//加写锁,写入value值try{//重新检查 value值是否已经被其他线程写入if(value == null){value = "value";//写入数据}}finally{lock.writeLock().unlock();}lock.readLock().lock();}}finally{lock.readLock().unlock();}return value;}

示例2–多线程环境下的读写锁使用

package constxiong.interview; import java.util.HashMap;import java.util.Map;import java.util.Random;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock; /** * 测试可重入 读写锁 * @author ConstXiong * @date 2019-06-10 11:19:42 */public class TestReentrantReadWriteLock {private Map<String, Object> map = new HashMap<String, Object>();private ReadWriteLock lock = new ReentrantReadWriteLock();/** * 根据 key 获取 value * @param key * @return */public Object get(String key) {Object value = null;lock.readLock().lock();try {Thread.sleep(50L);value = map.get(key);} catch (InterruptedException e) {e.printStackTrace();} finally {lock.readLock().unlock();}return value; }/** * 设置key-value * @param key * @return */public void set(String key, Object value) {lock.writeLock().lock();try {Thread.sleep(50L);map.put(key, value);} catch (InterruptedException e) {e.printStackTrace();} finally {lock.writeLock().unlock();}} //测试5个线程读数据,5个线程写数据public static void main(String[] args) {final TestReentrantReadWriteLock test = new TestReentrantReadWriteLock();final String key = "lock";final Random r = new Random();for (int i = 0; i <5; i++) {new Thread(){@Overridepublic void run() {for (int j = 0; j <10; j++) {System.out.println(Thread.currentThread().getName() + " read value=" + test.get(key));}}}.start();new Thread(){@Overridepublic void run() {for (int j = 0; j <10; j++) {int value = r.nextInt(1000);test.set(key, value);System.out.println(Thread.currentThread().getName() + " write value=" + value);}}}.start();}}}

给TA打赏
共{{data.count}}人
人已打赏
Java

同步和异步有何异同,分别在什么情况下使用?

2020-7-31 1:08:20

Java

创建进程需要()

2020-7-31 1:11:40

本站所发布的一切源码、模板、应用等文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权。本站内容适用于DMCA政策。若您的权利被侵害,请与我们联系处理,站长 QQ: 84087680 或 点击右侧 私信:盾给网 反馈,我们将尽快处理。
⚠️
本站所发布的一切源码、模板、应用等文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权。本站内容适用于DMCA政策
若您的权利被侵害,请与我们联系处理,站长 QQ: 84087680 或 点击右侧 私信:盾给网 反馈,我们将尽快处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索