JUC——线程同步锁(ReentrantLock)
ReentrantLock简介
ReentrantLock是一个可重复的互斥锁,又被称为独占锁,可重入的意思是:ReentrantLock锁可以被单个线程多次获取。但是在同一个时间点只能被一个线程锁持有
ReentrantLock使用一个FIFO(先进先出)的等待队里来管理获取该锁所有线程的。
ReentrantLock是一个独占锁,在获取锁的之后其所有的操作都是线程独享的,其他的线程在没有获取到锁之前都需要等待。
public class ReentrantLock implements Lock,java.io.Serializable
ReentrantLock之中分为公平锁与非公平锁,它们的区别体现在获取锁的机制上是否公平以及执行速度上。、
这两种锁的启用也是非常容易控制的,这个类提供的构造方法如下:
- 无参构造(非公平锁,NonfairSync)
public ReentrantLock() {
sync = new NonfairSync();
} - 有参构造
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
//fair = true,表示公平锁,FairSync
//fair = false,表示非公平锁,NonfairSync
ReentrantLock继承结构
范例:使用ReentrantLock定义一个多线程卖票的处理程序
package so.strong.mall.concurrent;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; class Ticket {
private Lock myLock = new ReentrantLock(); //非公平锁
private int count = 10; //一共10张票
public void sale() {
myLock.lock(); //进入到阻塞状态,一直到unlock执行后解除阻塞
try {
if (this.count > 0) {
System.out.println(Thread.currentThread().getName() + "卖票,ticket=" + this.count--);
}
} finally {
myLock.unlock(); //不管最终结果如何一定要进行解锁
}
}
} public class TestDemo {
public static void main(String[] args) {
final Ticket ticket = new Ticket(); //多线程要共享同一个数据资源
for (int i = 0; i < 6; i++) {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
ticket.sale(); //卖票处理
}
}
}).start();
}
}
}
Thread-0卖票,ticket=10
Thread-0卖票,ticket=9
Thread-0卖票,ticket=8
Thread-0卖票,ticket=7
Thread-0卖票,ticket=6
Thread-0卖票,ticket=5
Thread-0卖票,ticket=4
Thread-2卖票,ticket=3
Thread-2卖票,ticket=2
Thread-2卖票,ticket=1
当前的代码要比直接使用synchronized更加容易,而且锁的处理机制更加的直观。通过查看源代码可以发现,使用lock()进行锁定的时候会考虑两种情况:
Sync-java.util.concurrent.locks.ReentrantLock
- FairSync-java.util.concurrent.locks.ReentrantLock
- NonFairSync-java.util.concurrent.locks.ReentrantLock
在进行公平锁处理的时候每当锁定一个线程对象就会使用“acquire(1)”方法进行表示:
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
在进行解锁时会使用一个"sync.release(1)”释放方法, 1 表示释放一个:
public void unlock() {
sync.release(1);
}
JUC——线程同步锁(ReentrantLock)的更多相关文章
- JUC——线程同步锁(Condition精准控制)
在进行锁处理的时候还有一个接口:Condition,这个接口可以由用户来自己进行锁的对象创建. Condition的作用是对锁进行更精确的控制. Condition的await()方法相当于Objec ...
- JUC——线程同步锁(锁处理机制简介)
锁处理机制简介 juc的开发框架解决的核心问题是并发访问和数据安全操作问题,当进行并发访问的时候如果对于锁的控制不当,就会造成死锁这样的阻塞问题. 为了解决这样的缺陷,juc里面重新针对于锁的概念进行 ...
- JUC——线程同步锁(ReentrantReadWriteLock读写锁)
读写锁简介 所谓的读写锁值得是两把锁,在进行数据写入的时候有一个把“写锁”,而在进行数据读取的时候有一把“读锁”. 写锁会实现线程安全同步处理操作,而读锁可以被多个对象读取获取. 读写锁:ReadWr ...
- JUC——线程同步锁(LockSupport阻塞原语)
java.util.concurrent.locks.LockSupport这个是一个独立的类,这个类的主要功能是用来解决Thread里面提供的suspend()(挂起线程).resume()(恢复运 ...
- Python之路(第四十四篇)线程同步锁、死锁、递归锁、信号量
在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock ...
- 同步锁——ReentrantLock
本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 Lock接口简介 在JUC包下面有一个java.util ...
- Java 基础【07】线程同步锁的选择
在需要线程同步的时候如何选择合适的线程锁? 例:选择可以存入到常量池当中的对象,String对象等 public class SyncTest { private String name = &quo ...
- 多线程 - 线程同步锁(lock、Monitor)
1. 前言 多线程编程的时候,我们不光希望两个线程间能够实现逻辑上的先后顺序运行,还希望两个不相关的线程在访问同一个资源的时候,同时只能有一个线程对资源进行操作,否则就会出现无法预知的结果. 比如,有 ...
- java基础---Java---面试题---银行业务调度系统(线程同步锁、枚举、线程池)
银行业务调度系统的项目需求: 模拟实现银行业务调度系统逻辑,具体需求如下: Ø 银行内有6个业务窗口,1- 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口. Ø 有三种对应类 ...
随机推荐
- Cloudera Manager 4.6 安装部署hadoop CDH集群
Cloudera Manager 4.6 安装详解 1. Cloudera Manager介绍 1.1. 功能介绍 Cloudera Manager是一个针对hadoop集群的管理工具,功能包括:cd ...
- Charles应用指南--安装与代理篇
Charles是开发测试过程中十分常用的一款代理软件,之前也写了一点基本使用.最近有新同事入职头一次用这个,就写了这么一份基本的安装和配置笔记. Charles 下载地址 mac:链接: https: ...
- Windows 7防火墙阻止了远程桌面连接的解决方法
在[系统属性]中已经设置了允许远程桌面连接了,但是还是不能远程桌面的话,很可能是你的windows防火墙处于“启用”状态,防火墙阻止了windows 7系统的远程桌面连接.你可以使用以下的方法检查解决 ...
- 丢手绢问题(约瑟夫问题)的python实现
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉. def fnA(p, personNum, cnt): times = cnt // pe ...
- c语言学习——安装
作为颜控,选择了vs2019 工作组件选择c++,vs扩展开发. 默认安装就行了 安装成功,附图
- filebeat+logstash+elasticsearch收集haproxy日志
filebeat用于是日志收集,感觉和 flume相同,但是用go开发,性能比较好 在2.4版本中, 客户机部署logstash收集匹配日志,传输到 kafka,在用logstash 从消息队列中抓取 ...
- c++——register关键字、struct类型、bool关键字、三目运算符
register关键字增强 //register关键字 请求编译器让变量a直接放在寄存器里面,速度快 //在c语言中 register修饰的变量 不能取地址,但是在c++里面做了内容 /* //1 r ...
- vue-cli 安装失败Failed to download repo vuejs-templates/vuedemo: Response code 404 (Not Found)
还原问题现场: 第一次使用vue init webpack projectName的时候,由于操作失误,执行了两次npm install -g vue-cli,然后再使用vue init webpac ...
- Apache24 + php5.6.31 +Sql server R2 环境搭建①
win8(7)x64系统下 :PHP5.5.15 + Apache2.4.10 + SQL server 2008 R2 的配置方法分享给大家,32位的同理,不过下载的软件需要也是32位的. 好久未 ...
- oracle常用视图v$mystat v$sesstat v$sysstat v$statname v$thread v$ parameter v$session v$process
这两天看了盖国强老师的<<深入浅出>>,很佩服盖老师钻研的精神.书中常用到一个查询语句,为了获取当前会话的跟踪文件路径,sql如下: SELECT d.VALUE || '/' ...