java中的读/写锁
读写锁接口:ReadWriteLock,它的具体实现类为:ReentrantReadWriteLock
使用场景:
对于一个资源,读读能共存,读写不能共存,写写不能共存。
锁降级:从写锁变成读锁;
锁升级:从读锁变成写锁。
ReentrantReadWriteLock不支持锁升级,支持锁降级
ReadWriteLock rtLock = new ReentrantReadWriteLock();
rtLock.readLock().lock();
System.out.println("get readLock.");
rtLock.writeLock().lock();
System.out.println("blocking");
会死锁
ReadWriteLock rtLock = new ReentrantReadWriteLock();
rtLock.writeLock().lock();
System.out.println("writeLock"); rtLock.readLock().lock();
System.out.println("get read lock");
不会死锁
案例应用:
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; public class CacheDemo {
/**
* 缓存器,这里假设需要存储1000左右个缓存对象,按照默认的负载因子0.75,则容量=750,大概估计每一个节点链表长度为5个
* 那么数组长度大概为:150,又有雨设置map大小一般为2的指数,则最近的数字为:128
*/
private Map<String, Object> map = new HashMap<>(128);
private ReadWriteLock rwl = new ReentrantReadWriteLock();
public static void main(String[] args) { }
public Object get(String id){
Object value = null;
rwl.readLock().lock();//首先开启读锁,从缓存中去取
try{
value = map.get(id);
if(value == null){ //如果缓存中没有释放读锁,上写锁
rwl.readLock().unlock();
rwl.writeLock().lock();
try{
if(value == null){ //防止多写线程重复查询赋值
value = "redis-value"; //此时可以去数据库中查找,这里简单的模拟一下
}
rwl.readLock().lock(); //加读锁降级写锁,不明白的可以查看上面锁降级的原理与保持读取数据原子性的讲解
}finally{
rwl.writeLock().unlock(); //释放写锁
}
}
}finally{
rwl.readLock().unlock(); //最后释放读锁
}
return value;
}
}
如果不使用锁降级功能,如先释放写锁,然后获得读锁,在这个get过程中,可能会有其他线程竞争到写锁 或者是更新数据 则获得的数据是其他线程更新的数据,可能会造成数据的污染,即产生脏读的问题。
java中的读/写锁的更多相关文章
- java中ReentrantReadWriteLock读写锁的使用
Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. 读写锁:分为读 ...
- Java中的读写锁
一.读写锁 1.初识读写锁 a)Java中的锁——Lock和synchronized中介绍的ReentrantLock和synchronized基本上都是排它锁,意味着这些锁在同一时刻只允许一个线程进 ...
- 22、Java并发性和多线程-Java中的读/写锁
以下内容转自http://ifeve.com/read-write-locks/: 相比Java中的锁(Locks in Java)里Lock实现,读写锁更复杂一些.假设你的程序中涉及到对一些共享资源 ...
- 【练习】Java中的读文件,文件的创建,写文件
前言 大家好,给大家带来Java中的读文件,文件的创建,写文件的概述,希望你们喜欢 读文件 public static void read(String path,String filename){ ...
- Java中的读文件,文件的创建,写文件
前言 大家好,我是 Vic,今天给大家带来Java中的读文件,文件的创建,写文件的概述,希望你们喜欢 示意图 读文件 public static void read(String path,Strin ...
- Java 并发包中的读写锁及其实现分析
1. 前言 在Java并发包中常用的锁(如:ReentrantLock),基本上都是排他锁,这些锁在同一时刻只允许一个线程进行访问,而读写锁在同一时 刻可以允许多个读线程访问,但是在写线程访问时,所有 ...
- java多线程:并发包中ReentrantReadWriteLock读写锁的原理
一:读写锁解决的场景问题--->数据的读取频率远远大于写的频率的场景,就可以使用读写锁.二:读写锁的结构--->用state一个变量.将其转化成二进制,前16位为高位,标记读线程获取锁的次 ...
- java多线程:并发包中ReentrantReadWriteLock读写锁的锁降级模板
写锁降级为读锁,但读锁不可升级或降级为写锁. 锁降级是为了让当前线程感知到数据的变化. //读写锁 private ReentrantReadWriteLock lock=new ReentrantR ...
- java并发编程-读写锁
最近项目中需要用到读写锁 读写锁适用于读操作多,写操作少的场景,假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁.在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以 ...
随机推荐
- Android(java)学习笔记103:Framework运行环境之 Android进程产生过程
1. 前面Android(java)学习笔记159提到Dalvik虚拟机启动初始化过程,就下来就是启动zygote进程: zygote进程是所有APK应用进程的父进程:每当执行一个Android应用程 ...
- 【洛谷5113】Sabbat of the witch(毒瘤分块)
点此看题面 大致题意: 给你一个序列,要你支持三种操作:区间赋值,区间求和,撤回之前任一区间赋值操作. 分块 这道题应该是一道十分毒瘤的分块题. 这道题要用到的算法并不是很难,但是思维难度是真的高. ...
- tableViewcell上放定时器
tableviewcell上的定时器: 1.创建一个管理定时器的TimerManger类, TimerManger.h #import <Foundation/Foundation.h> ...
- 利用kvo实现列表倒计时
自己稍微记录一下,方便以后用到: 先创建一个定时器的类: #import "TimeCenter.h" @interface TimeCenter () @property (no ...
- Feign + Hystrix 服务熔断和服务降级
本机IP为 192.168.1.102 1. 新建 Maven 项目 feign 2. pom.xml <project xmlns="http://maven.apa ...
- opencv anaconda
from: http://blog.csdn.net/fairylrt/article/details/43560525 Anaconda是一个python的一个包装,或者不单单是这样.你可以认为An ...
- Java实现随机出题,10道10以内加减法计算
package com.swift; import java.awt.Toolkit; import java.util.Scanner; public class PlusQuiz { public ...
- ceph 性能
mysql在以下设备备份耗时,供大家参考: 备份文件大小 sata用时 ceph用时 nas挂载sata盘用时 7G 1分钟 15G 2分钟 21分钟 47G 8分钟 82分钟 274 ...
- 在基于vue-cli的项目自定义打包环境
在工作当中,遇到了下面这个问题: 测试环境与生产环境中的用户权限不一样,因此,就需要根据测试环境打一个包,生产环境又打一个包.可是,如果每次打包都需要更改权限的配置文件的话,会很麻烦,而且,体现不出一 ...
- linux 基本指令 归类
今天 我们来学习一下 最最基础的linux 指令,在我看来 linux的操作就是 增 删 改 查 这四个字. 1 查询 操作用户 woami 2查询登录用户 who am i 2 pwd //查询当前 ...