java并发初探ReentrantWriteReadLock
java并发初探ReentrantWriteReadLock
ReenWriteReadLock类的优秀博客
ReentrantReadWriteLock读写锁详解
Java多线程系列--“JUC锁”08之 共享锁和ReentrantReadWriteLock
ReentrantWriteReadLock类实现

@startuml
interface Lock
interface ReadWriteLock
class ReentrantReadWriteLock{
Sync sync
ReentrantReadWriteLock.ReadLock readerLock;
ReentrantReadWriteLock.WriteLock writerLock;
}
ReadWriteLock <|-- ReentrantReadWriteLock
ReentrantReadWriteLock --o ReadLock
ReentrantReadWriteLock --o WriteLock
ReentrantReadWriteLock --o Sync
AbstractQueuedSynchronizer <|- Sync
Lock <|-- ReadLock
Lock <|-- WriteLock
@enduml
特点
ReentrantWriteReadLock内部有读锁和写锁。
写锁是独占锁
当前线程持有写锁,其他线程只能等待
当其他线程拥有对象的写锁或者读锁,当前线程等待获取写锁
读锁是共享锁
没有其他线程的写锁,当前线程可以获取读锁
使用例子
package com.java.javabase.thread.base.concurrent.lock;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Slf4j
public class ReentranReadWriteLockTest {
/**
* @author
* @version
* @since
*/
public static void main(String[] args) {
ReentranReadWriteLockTest test =new ReentranReadWriteLockTest();
User user =test.new User("jack",test.new Count("001",1000));
for(int i=0;i<3;i++)
{
user.printCash();
user.setCash(1000);
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Count {
private String id;
private int cash;
}
@Data
class User {
private String name;
private Count count;
private ReadWriteLock readWriteLock;
public User(String name, Count count) {
this.name = name;
this.count = count;
this.readWriteLock = new ReentrantReadWriteLock();
}
public void setCash(final int cash) {
new Thread() {
@Override
public void run() {
readWriteLock.writeLock().lock();
try {
log.info("thread {} :user {} set cash {} start",
Thread.currentThread().getName(), name, cash);
Thread.sleep(1000);
log.info("thread {} :user {} current cash = {}",
Thread.currentThread().getName(), name, count.getCash());
count.setCash(cash);
log.info("thread {} :user {} set cash {} end",
Thread.currentThread().getName(), name, cash);
} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
readWriteLock.writeLock().unlock();
}
}
}.start();
}
public void printCash() {
new Thread() {
@Override
public void run() {
try {
readWriteLock.readLock().lock();
log.info("thread {} :user {} get cash start", Thread.currentThread().getName(), name);
log.info("thread {} :user {} current cash = {}",
Thread.currentThread().getName(), name, count.getCash());
Thread.sleep(1000);
log.info("thread {} :user {} get cash end", Thread.currentThread().getName(), name);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readWriteLock.readLock().unlock();
}
}
}.start();
}
}
}
例子结果
2019-08-09 10:49:15,618 [Thread-0] INFO ReentranReadWriteLockTest - thread Thread-0 :user jack get cash start
2019-08-09 10:49:15,618 [Thread-0] INFO ReentranReadWriteLockTest - thread Thread-0 :user jack current cash = 1000
2019-08-09 10:49:16,618 [Thread-0] INFO ReentranReadWriteLockTest - thread Thread-0 :user jack get cash end
2019-08-09 10:49:16,618 [Thread-1] INFO ReentranReadWriteLockTest - thread Thread-1 :user jack set cash 1000 start
2019-08-09 10:49:17,618 [Thread-1] INFO ReentranReadWriteLockTest - thread Thread-1 :user jack current cash = 1000
2019-08-09 10:49:17,618 [Thread-1] INFO ReentranReadWriteLockTest - thread Thread-1 :user jack set cash 1000 end
2019-08-09 10:49:17,618 [Thread-4] INFO ReentranReadWriteLockTest - thread Thread-4 :user jack get cash start
2019-08-09 10:49:17,618 [Thread-2] INFO ReentranReadWriteLockTest - thread Thread-2 :user jack get cash start
2019-08-09 10:49:17,618 [Thread-4] INFO ReentranReadWriteLockTest - thread Thread-4 :user jack current cash = 1000
2019-08-09 10:49:17,618 [Thread-2] INFO ReentranReadWriteLockTest - thread Thread-2 :user jack current cash = 1000
2019-08-09 10:49:18,618 [Thread-4] INFO ReentranReadWriteLockTest - thread Thread-4 :user jack get cash end
2019-08-09 10:49:18,618 [Thread-2] INFO ReentranReadWriteLockTest - thread Thread-2 :user jack get cash end
2019-08-09 10:49:18,618 [Thread-5] INFO ReentranReadWriteLockTest - thread Thread-5 :user jack set cash 1000 start
2019-08-09 10:49:19,617 [Thread-5] INFO ReentranReadWriteLockTest - thread Thread-5 :user jack current cash = 1000
2019-08-09 10:49:19,617 [Thread-5] INFO ReentranReadWriteLockTest - thread Thread-5 :user jack set cash 1000 end
2019-08-09 10:49:19,617 [Thread-3] INFO ReentranReadWriteLockTest - thread Thread-3 :user jack set cash 1000 start
2019-08-09 10:49:20,617 [Thread-3] INFO ReentranReadWriteLockTest - thread Thread-3 :user jack current cash = 1000
2019-08-09 10:49:20,617 [Thread-3] INFO ReentranReadWriteLockTest - thread Thread-3 :user jack set cash 1000 end
java并发初探ReentrantWriteReadLock的更多相关文章
- java并发初探ConcurrentSkipListMap
java并发初探ConcurrentSkipListMap ConcurrentSkipListMap以调表这种数据结构以空间换时间获得效率,通过volatile和CAS操作保证线程安全,而且它保证了 ...
- java并发初探ConcurrentHashMap
java并发初探ConcurrentHashMap Doug Lea在java并发上创造了不可磨灭的功劳,ConcurrentHashMap体现这位大师的非凡能力. 1.8中ConcurrentHas ...
- java并发初探ThreadPoolExecutor拒绝策略
java并发初探ThreadPoolExecutor拒绝策略 ThreadPoolExecuter构造器 corePoolSize是核心线程池,就是常驻线程池数量: maximumPoolSize是最 ...
- java并发初探CyclicBarrier
java并发初探CyclicBarrier CyclicBarrier的作用 CyclicBarrier,"循环屏障"的作用就是一系列的线程等待直至达到屏障的"瓶颈点&q ...
- java并发初探CountDownLatch
java并发初探CountDownLatch CountDownLatch是同步工具类能够允许一个或者多个线程等待直到其他线程完成操作. 当前前程A调用CountDownLatch的await方法进入 ...
- java并发:初探sleep方法
sleep与wait sleep是Thread方法,使得当前线程从运行态变为阻塞态.但它不会释放对象的锁. wait方法是Object方法,它的作用是使得当前拥有对象锁的线程从运行态变为阻塞态, 它会 ...
- java并发队列
阻塞队列 常见的阻塞队列有ArrayBlockingQueue,LinkedBlockingDeque,LinkedBlockingQueue,这些队列有界且可以阻塞线程 ArrayBlockingQ ...
- Java并发基础框架AbstractQueuedSynchronizer初探(ReentrantLock的实现分析)
AbstractQueuedSynchronizer是实现Java并发类库的一个基础框架,Java中的各种锁(RenentrantLock, ReentrantReadWriteLock)以及同步工具 ...
- java并发编程资料
并发这玩意很有用,把自己在网上看过觉得总结的很好的资料分享出来.猛击下面的地址查看吧 java并发编程:线程池的使用说明 java并发编程系列文章 Java并发性和多线程专题 并发工具类 Java 7 ...
随机推荐
- C++中的拷贝构造函数
一.拷贝构造函数: 格式: A(const A& a); 总结: 系统为对象B分配了内存并完成了与对象testA的复制过程,就类对象而言,相同类型的类对象是通过拷贝构造函数来完成整个复制过 ...
- The Preliminary Contest for ICPC Asia Nanjing 2019 - D Robots(概率dp+拓扑排序)
这题概率dp + 拓扑排序可以写 改天补解释 #include <bits/stdc++.h> using namespace std; const int maxn=1e5+10; ve ...
- typo3 网站迁移
最近再弄这个typo3,虽然说看不怎么动,但是迁移嘛,最笨的办法就是整体过去,就是数据量太大了,哈哈,我先写一下我的笨办法: 注意:每个版本的typo3对php,mysql,apache的版本都有要求 ...
- Java学习资源 - 其他
http请求HttpServletRequest详解 HttpServletRequest请求转发 高并发场景下的httpClient优化使用 HttpClien高并发请求连接池 - PoolingH ...
- C++11常用特性介绍——constexpr变量
一.constexpr变量 1)将变量声明为constexpr类型以便由编译器来验证变量的值是否为一个常量表达式,声明为constexpr的变量一定是一个常量,而且必须用常量表达式来初始化,如: in ...
- rem布局,在用户调整手机字体大小/用户调整浏览器字体大小后,布局错乱问题
一.用户调整浏览器字体大小,影响的是从浏览器打开的web页. 浏览器设置字体大小,影响浏览器打开的页面.通过js可控制用户修改字体大小,使页面不受影响. (function(doc, win) { / ...
- 区分移动端和pc端
区分移动端和pc端: window.navigator.userAgent.toLowerCase().indexOf('mobile')== -1 判断 等于-1就是pc,false就是移动端 ...
- mysql 表这段内容替换
update `cr_article` set `img`=replace(`img`,'http://192.168.2.10/upload','http://zouke1220.oss-cn-be ...
- TCP通讯代码
服务端代码: import socket server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 使用固定端口 server_ ...
- 「快学Docker」Docker简介、安装和Hello World实现
前言 Docker已经成为了一门炙手可热的技术,每个程序员(特别是后端程序员)都应该学习下Docker这门技术. Docker是什么 来自官网的定义:Docker是以Docker容器为资源分割和调度的 ...