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 ...
随机推荐
- Linux - 终端terminal进入交互环境的快捷键
1. 上一页 ctrl + b 2. 下一页 空格 / ctrl + f 3. 上半页 ctrl + u 4. 下半页 ctrl + d 5. 上一行 k 6. 下一行 j 7. 向上查找 ?key ...
- Redis注意点记录
场景:1主2从 1.不使用哨兵模式,则当主机宕机后,从机并不会自动切换到Master状态,仍旧是Slave,若主机重新恢复,则从机进行自动连接 2.使用哨兵模式后,主机宕机,从机会根据分配的权值在从机 ...
- DHCP原理及报文格式
DHCP原理及报文格式 DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是IETF为实现IP的自动配置而设计的协议,它可以为客户机自动分配IP地址. ...
- 关于转入软件工程专业后第二次java课上作业的某些体会
今天是第二周的java课. 自从转入了软件工程专业后,在我没有学习c++的基础上,直接开始了学习java的过程.不得不说过程很艰辛.今天下午老师让编写一个随机产生作业的软件.而我的基础差到都不知道如何 ...
- Update(stage3):第1节 redis组件:7、持久化
7.redis的持久化 由于redis是一个内存数据库,所有的数据都是保存在内存当中的,内存当中的数据极易丢失,所以redis的数据持久化就显得尤为重要,在redis当中,提供了两种数据持久化的方式, ...
- 基于Facebook开源框架SocketRocket的即时通讯
SocketRocket 介绍: SocketRock 是 Facebook 开源的框架,基于 WebSocket 客户端类库,适用于 iOS.Mac OS.tv OS.GitHub 传送门:http ...
- python3 getopt用法
python channel_builder.py -s /Users/graypn/ -d /Users/graypn/Documents -m 7 --out=report/xx.html 参数也 ...
- 计算机网络 - TCP/IP模型
图片来自网上资料
- Java 笔试题
有一些还是存在问题,欢迎大家一起探讨. 在Java类中,使用以下( )声明语句来定义公有的int型常量MAX. A. public int MAX = 100; B. final int MAX = ...
- UIView动画的使用
下面介绍三种简单的UIView动画的使用,如果在项目中对动画没有太多“细致化”的设计要求,基本够用了. 一.首尾式动画 说明:如果只是修改控件的属性,使用首尾式动画还是很方便的,如果还需要在动画完成后 ...