技术标签: ReentrantLock java多线程
以下是摘自JAVA API文档关于lock和synchronized的一段话:
Lock
实现提供了比使用 synchronized
方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关Condition对象。synchronized
方法或语句的使用提供了对与每个对象相关的隐式监视器锁的访问,但却强制所有锁获取和释放均要出现在一个块结构中:当获取了多个锁时,它们必须以相反的顺序释放,且必须在与所有锁被获取时相同的词法范围内释放所有锁。先看一下Lock接口的定义的方法:
注意:synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中
Lock接口的实现类:ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock 。其中ReadLock和WriteLock是ReentrantReadWriteLock的内部类,ReentrantReadWriteLock是ReadWriteLock的实现类。关于ReadWriteLock后续再做详解。
一个可重入的互斥锁,它拥有与 synchronized 相同的并发性和内存语义,但是添加了类似轮询锁、定时锁等候和可中断锁等候的一些特性。构造方法:
ReentrantLock特有的方法:
如下实现两个线程轮询处理公共数据:
public class ReenLockTest {
public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
Thread1.m1();
}
},"thread1").start();
new Thread(new Runnable(){
@Override
public void run() {
Thread1.m2();
}
},"thread2").start();
}
static ReentrantLock lock = new ReentrantLock();
static ReentrantLock lock2 = new ReentrantLock();
static int i = 100;
static class Thread1{
public static void m1(){
while(i>0){
lock.lock();
try {
System.out.println("method m1()" + i--);
} catch (Exception e) {
e.printStackTrace();
}finally{
if(!lock2.isLocked())
lock2.unlock();
}
}
}
public static void m2(){
while(i>0){
lock2.lock();
try {
System.out.println("method m2()" + i--);
} catch (Exception e) {
e.printStackTrace();
}finally{
if(!lock.isLocked())
lock.unlock();
}
}
}
}
}
ReentrantLock锁,可以被单个线程多次获取:
如果该锁没有被另一个线程保持,并且立即返回 true
值,则将锁的保持计数设置为 1。即使已将此锁设置为使用公平排序策略,但是调用 tryLock()
仍将 立即获取锁(如果有可用的),而不管其他线程当前是否正在等待该锁。
true
。false
值。tryLock()的用法与lock()的使用方式基本相同,只是在释放锁时,tryLock()方式获取的锁需要先验证当前线程是否获取到锁isLocked()
static class Thread1{
public static void m1(){
while(i>0){
boolean tryLock = lock.tryLock();
if(tryLock){
try {
Thread.sleep(500);
System.out.println("method m1()" + i--);
} catch (Exception e) {
e.printStackTrace();
}finally{
if(lock.isLocked())
lock.unlock();
}
}
}
}
lockInterruptibly() 与lock() 的区别:
public class TryLockTest {
static Lock lock = new ReentrantLock();
static Lock lock2 = new ReentrantLock();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
m1();
}
});
Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
m2();
}
});
t1.start();
t2.start();
t1.interrupt();
t2.interrupt();
}
public static void m1(){
lock.lock();
for(int i=0 ;i<20 ; i++){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("m1() java.lang.InterruptedException");
}
System.out.println("m1 *running");
}
lock.unlock();
}
public static void m2(){
try {
lock2.lockInterruptibly();
for(int i=0 ;i<20 ; i++){
Thread.sleep(500);
System.out.println("m2 **running");
}
} catch (InterruptedException e) {
System.out.println("m2() java.lang.InterruptedException");
}finally{
if(((ReentrantLock) lock2).isLocked())
lock2.unlock();
}
}
}
输出结果:
从输出结果中可以看到,m1()执行,而m2()被打断。
注意:
关于线程中断请看这篇博客:Java并发之线程中断
文章浏览阅读3.9k次。获取【下载地址】 QQ: 313596790 【免费支持更新】三大数据库mysql oracle sqlsever 更专业、更强悍、适合不同用户群体【新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统】A 集成代码生成器(开发利器)+快速构建表单; QQ:313596790freemaker模版技术 ,0个代码不用写,生成完_电商 dubbo zookeeper activemq fastdfs redis eginx 架构
文章浏览阅读5k次,点赞6次,收藏41次。下面将介绍罚函数法,并且对等式约束不等式约束适用内点法还是外点法做了说明,与如何选取罚函数。并且给与相应例题。罚函数的基本思想是,借助罚函数把约束问题转化为无约束问题,进而用无约束最优化方法求解。提示:这里对文章进行总结:例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。_罚函数法例题讲解
文章浏览阅读1.2k次。到现在,我们已经可以让组件独立地显示。我们只是运行它、让它显示在Web UI中。让我们把组件整合进导航栏,使我们可以在正常登录Web UI时访问它。 步骤一: 为你的UI组件主窗体创建一个内向插件。 步骤二: 将你的组件的主窗体在运行时资源库中作为一个界面视图暴露出来(Interface View)。 步骤三:_sap crm如何将组件添加到导航
文章浏览阅读8.5k次,点赞9次,收藏34次。1.简述GPS载波相位测量的基本原理?载波相位测量的观测量是GPS接收机所接收的卫星载波信号与接收机本振参考信号的相位差。以#[(4)表示k接收机在接收机钟面时刻4%时所接收到的j卫星载波信号的相位值,φ。(t)表示ht接收机在钟面时刻i时所产生的本地参考信号的相位值,则k接收机在接收机钟面时刻t时观测j卫星所取得的相位观测量可写为中(tn) =中o(tr) - p’(5n)通常的相位或相位..._载波相位测量的相位csdn
文章浏览阅读265次。如何在Linux下安装JDK和Nginx?Linux下安装JDK把 JDK 的安装包上传到服务器,目录如下 /user/local/java然后我们需要解压安装包解压 tar zxvf jdk-8u301-linux-x64.tar.gz解压完成后,JDK 的安装目录就出现了,复制目录路径 /usr/local/java/jdk1.8.0_301我们安装完 JDK 之后,是不是还需要配置环境变量让 JDK 生效,接下来就是配置环境变量的操作了。3.配置环境变量vim /etc/pr_ngnix安装后需要安装jdk
文章浏览阅读243次。题面背景每天中午的下课铃一响,浙江镇海中学(什么?镇海中学)的同学们都会冲出学校来附近的小饭馆吃饭,刹那间天昏地暗,飞砂走石,家家餐馆内都是一片黑压压的人 。馄饨店、饺子馆,在学校附近开一家红一家。身为镇海中学信息中心首席科学顾问兼资深信息学竞赛辅导老师Dennis看到了,他为了在业余时间方便学生,他租了学校附近的一家店面,雇了几个拉面师傅,开了一家“正宗兰州牛肉拉面馆”,生意还不错。..._配方编程c++
文章浏览阅读2w次,点赞3次,收藏17次。1、linux下查看所有占用端口情况netstat -ntlp2、查看所有某个端口使用情况,如80端口。netstat -ntulp |grep 803、查看一台服务器上面哪些服务及端口。netstat -lanp4、查看一个服务有几个端口,比如要查看mysqld。ps -ef |grep mysqldnetstat命令各个参数说明如下:-a..._linux 机器如何查看大量处于tcp_wait 的端口是哪个
文章浏览阅读68次。创建时间:2007-09-11文章属性:原创文章提交:wzt (wzt_at_xsec.org)Linux后门系列--由浅入深sk13完全分析(缩水版)作者 wzt联系方式 [email protected]个人网站 http://tthacker.cublog.cn http://xsec.org本文首发《***防线》第八期,本文在《黑防》里有更详细更细致..._get_sct()
文章浏览阅读823次。docker config # 查看已创建配置文件 - docker config ls # 将已有配置文件添加到docker配置文件中 - docker config create docker 配置文件名 本地配置文件 docker node # 查看集群中的节点 - docker node ls # 将m..._修改了swarm-base.yml文件,怎么重启
文章浏览阅读422次。[HAOI2011]Problem bDescription对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。Input第一行一个整数n,接下来n行每行五个整数,分别表示a、b、c、d、k100%的数据满足:1≤n≤50000,1≤a≤b≤50000_[haoi2011] 问题b
文章浏览阅读1.4k次。列表框架还有一个QListWidget,它是QListView的子类,与QListView不同的是,它已经建立了一个数据储存模型QListWidgetItem,直接调用addItem()函数就可以添加条目(Item),常用的事件类型有: 事件类型 描述 currentItemChanged 列表中的条目发生改变时,触发此事件; itemClicked 点击列表中的条目时,触发此事件。 _pythonlist widget用法
文章浏览阅读8.4k次,点赞11次,收藏43次。IntroductionLongformer是一种可高效处理长文本的模型,出自AllenAI 2020年4月10日。目前已经开源,而且可以通过huggingface快速使用传统Transformer-based模型在处理长文本时存在一些问题,因为它们均采用"我全都要看"型的attention机制,即每一个token都要与其他所有token进行交互,无论是空间还是时间复杂度都高达O(n2)O(n^2)O(n2)。为了解决这个问题,之前有些工作是将长文本切分为若干个较短的Text Segment,然后逐个处_longformer