Java多线程之ReadWriteLock读写锁简介与使用教程
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6558073.html
普通的锁在对某一内容加锁后,其他线程是不能访问的。但是我们要考虑这种情况:如果当前加锁的内容中,有些操作是可以并发执行的,有些是不可以并发,两种操作之间又存在互斥,怎么才能最优化地加锁呢?我们引入了ReadWriteLock,人为地将这两种操作划分为 读、写 操作。(注意:这里的读、写 不是完全意义上的读写,只是用来标识两种加锁的操作),根据操作所加锁的不同,操作之间的互斥关系如下:读——读不互斥;读——写互斥;写——写互斥。也就是说,只有加了读锁的代码块之间可以并发执行,加了读锁的代码块与加了写锁的代码块互斥,加了写锁的代码块之间也互斥执行。
一:使用
创建读写锁:ReadWriteLock接口继承自Lock接口,实现类是ReentrantReadWriteLock。所以使用ReentrantReadWriteLock来创建读写锁,可以在构造函数中指明是否是公平锁。
获取读锁:读锁通过ReentrantReadWriteLock对象的 readLock() 返回一个Lock接口的实现类。
获取写锁:写锁通过ReentrantReadWriteLock对象的 writeLock() 返回一个Lock接口的实现类。
加锁:在需要加锁的地方用读/写锁的lock()加锁。
释放锁:在需要解锁的地方用读/写锁的 unlock()解锁。
二:例子
private static ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock();
private static Lock readLock = readWriteLock.readLock();
private static Lock writeLock = readWriteLock.writeLock();
public void run() {
if (ischeck) {
//上读锁
readLock.lock();
System.out.println("读:" + name + "正在查询" + myCount + "账户,当前金额为" + myCount.getCash());
//释放读锁
readLock.unlock();
} else {
//上写锁
writeLock.lock();
System.out.println("写:" + name + "正在操作" + myCount + "账户,金额为" + iocash +",当前金额为" + myCount.getCash());
myCount.setCash(myCount.getCash() + iocash);
System.out.println("写:" + name + "操作" + myCount + "账户成功,金额为" + iocash +",当前金额为" + myCount.getCash());
//释放写锁
writeLock.unlock();
}
}
三:JDK8中的改进——StampedLock
StampedLock是ReadWriteLock的一个改进。StampedLock与ReadWriteLock的区别在于,StampedLock认为读不应阻塞写。StampedLock认为读写互斥应该是指——不让读重复读同一数据,而不是不让写线程写。
StampedLock是一种偏向于写线程的改进,解决了读多写少时,使用ReadWriteLock会产生写线程饥饿现象。
Java多线程之ReadWriteLock读写锁简介与使用教程的更多相关文章
- java多线程 -- ReadWriteLock 读写锁
写一条线程,读多条线程能够提升效率. 写写/读写 需要“互斥”;读读 不需要互斥. ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作.只要没有 writer,读取锁 ...
- 12. ReadWriteLock 读写锁
package com.gf.demo11; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent. ...
- ReadWriteLock读写锁(八)
前言:在JUC ReentrantReadWriteLock是基于AQS实现的读写锁实现. ReadWriteLock中定义了读写锁需要实现的接口,具体定义如下: public interface R ...
- JAVA多线程之volatile 与 synchronized 的比较
一,volatile关键字的可见性 要想理解volatile关键字,得先了解下JAVA的内存模型,Java内存模型的抽象示意图如下: 从图中可以看出: ①每个线程都有一个自己的本地内存空间--线程栈空 ...
- GUC-9 ReadWriteLock : 读写锁
import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWrit ...
- ReadWriteLock: 读写锁
ReadWriteLock: 读写锁 ReadWriteLock: JDK1.5提供的读写分离锁,采用读写锁分离可以有效帮助减少锁竞争. 特点: 1).使用读写锁.当线程只进行读操作时,可以允许多个线 ...
- 22.ReadWriteLock读写锁
import java.util.Random; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.R ...
- Java多线程之ConcurrentSkipListMap深入分析(转)
Java多线程之ConcurrentSkipListMap深入分析 一.前言 concurrentHashMap与ConcurrentSkipListMap性能测试 在4线程1.6万数据的条件下, ...
- JAVA多线程之wait/notify
本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...
随机推荐
- 如何在Windows下运行linux shell脚本
在工作中情况会在碰到linux下进行执行shell的脚本,而就会使用shell的脚本,但经常使用的Windows的系统,而想在Windows电脑中进行直接shell的脚本,而不用再进行学习其它的脚本语 ...
- ArrayAdapter使用方法
ArrayAdapter是一个简单的适配器,他的作用是将一个数组中的内容放入listView中.listView的item必须为textView. MainActivity.java package ...
- dockerfile介绍
详细说明,阅读这篇文章吧:https://yeasy.gitbooks.io/docker_practice/image/build.html 注意点: 容器是一个进程,不是一个系统 dockerfi ...
- javascript中使用new与不使用实例化对象的区别
我们先来看个实例 function Me(name,age,job){ this.name = name; this.age = age; this.job = job; } 请问这以下两种实例化对象 ...
- go语言之进阶篇定时器重置
1.定时器重置 示例: package main import ( "fmt" "time" ) func main() { timer := time.New ...
- C# Newtonsoft.Json解析数组的小例子[转]
https://blog.csdn.net/Sayesan/article/details/79756738 C# Newtonsoft.Json解析数组的小例子 http://www.cnblog ...
- PHP操作数据库函数比较
常用的php语法连接mysql如下 <?php $link = mysql_connect('localhost', 'user', 'password'); mysql_select_db(' ...
- Android -- Interpolator
Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等. ...
- List 集合的交集
private void Test() { List<string> lsA = new List<string>(); lsA.Add("A"); lsA ...
- (转)Unity3D 游戏贴图(法线贴图,漫反射贴图,高光贴图)
原帖网址http://www.u3dpro.com/read.php?tid=207 感谢jdk900网友的辛苦编写 我们都知道,一个三维场景的画面的好坏,百分之四十取决于模型,百分之六十取决于贴图 ...