java并发-ReentrantLock的lock和lockInterruptibly的区别
ReentrantLock的加锁方法Lock()提供了无条件地轮询获取锁的方式,lockInterruptibly()提供了可中断的锁获取方式。这两个方法的区别在哪里呢?通过分析源码可以知道lock方法默认处理了中断请求,一旦监测到中断状态,则中断当前线程;而lockInterruptibly()则直接抛出中断异常,由上层调用者区去处理中断。
lock获取锁过程中,忽略了中断,在成功获取锁之后,再根据中断标识处理中断,即selfInterrupt中断自己。 acquire操作源码如下:
/**
*默认处理中断方式是selfInterrupt
*/
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
acquireQueued,在for循环中无条件重试获取锁,直到成功获取锁,同时返回线程中断状态。该方法通过for循正常返回时,必定是成功获取到了锁。
/**
*无条件重试,直到成功返回,并且记录中断状态
*/
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next =null; // help GC
failed =false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted =true;
}
}finally {
if (failed)
cancelAcquire(node);
}
}
可中断加锁,即在锁获取过程中不处理中断状态,而是直接抛出中断异常,由上层调用者处理中断。源码细微差别在于锁获取这部分代码,这个方法与acquireQueue差别在于方法的返回途径有两种,一种是for循环结束,正常获取到锁;另一种是线程被唤醒后检测到中断请求,则立即抛出中断异常,该操作导致方法结束。
/**
* Acquires in exclusive interruptible mode.
* @param arg the acquire argument
*/
private void doAcquireInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.EXCLUSIVE);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next =null; // help GC
failed =false;
return;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
}
}finally {
if (failed)
cancelAcquire(node);
}
}
结论:ReentrantLock的中断和非中断加锁模式的区别在于:线程尝试获取锁操作失败后,在等待过程中,如果该线程被其他线程中断了,它是如何响应中断请求的。lock方法会忽略中断请求,继续获取锁直到成功;而lockInterruptibly则直接抛出中断异常来立即响应中断,由上层调用者处理中断。
那么,为什么要分为这两种模式呢?这两种加锁方式分别适用于什么场合呢?根据它们的实现语义来理解,我认为lock()适用于锁获取操作不受中断影响的情况,此时可以忽略中断请求正常执行加锁操作,因为该操作仅仅记录了中断状态(通过Thread.currentThread().interrupt()操作,只是恢复了中断状态为true,并没有对中断进行响应)。如果要求被中断线程不能参与锁的竞争操作,则此时应该使用lockInterruptibly方法,一旦检测到中断请求,立即返回不再参与锁的竞争并且取消锁获取操作(即finally中的cancelAcquire操作)
java并发-ReentrantLock的lock和lockInterruptibly的区别的更多相关文章
- 【多线程】Java并发编程:Lock(转载)
原文链接:http://www.cnblogs.com/dolphin0520/p/3923167.html Java并发编程:Lock 在上一篇文章中我们讲到了如何使用关键字synchronized ...
- [转载] java并发编程:Lock(线程锁)
作者:海子 原文链接: http://www.cnblogs.com/dolphin0520/p/3923167.html 出处:http://www.cnblogs.com/dolphin0520/ ...
- Java并发编程:Lock(转)
本文转自:http://www.cnblogs.com/dolphin0520/p/3923167.html Java并发编程:Lock 在上一篇文章中我们讲到了如何使用关键字synchronized ...
- 5、Java并发编程:Lock
Java并发编程:Lock 在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.l ...
- java 并发——ReentrantLock
java 并发--ReentrantLock 简介 public class ReentrantLock implements Lock, java.io.Serializable { // 继承了 ...
- 【java并发编程】Lock & Condition 协调同步生产消费
一.协调生产/消费的需求 本文内容主要想向大家介绍一下Lock结合Condition的使用方法,为了更好的理解Lock锁与Condition锁信号,我们来手写一个ArrayBlockingQueue. ...
- Java并发编程之Lock
重入锁ReentrantLock 可以代替synchronized, 但synchronized更灵活. 但是, 必须必须必须要手动释放锁. try { lock.lock(); } finally ...
- Java 并发开发:Lock 框架详解
摘要: 我们已经知道,synchronized 是Java的关键字,是Java的内置特性,在JVM层面实现了对临界资源的同步互斥访问,但 synchronized 粒度有些大,在处理实际问题时存在诸多 ...
- 【转】Java并发编程:Lock
阅读目录 一.synchronized的缺陷 二.java.util.concurrent.locks包下常用的类 三.锁的相关概念介绍 来自: http://www.importnew.com/18 ...
随机推荐
- centos7中,mysql连接报错:1130 - Host ‘118.111.111.111’ is not allowed to connect to this MariaDB server
客户端连接报错 这个问题是因为用户在数据库服务器中的mysql数据库中的user的表中没有权限. 解决步骤 1.连接服务器: mysql -u root -p 2.看当前所有数据库:show data ...
- django-导入应用包的搜索路径
创建应用包 在 settings.py注册和配置urls.py中要按顺序导入包名和应用名 settings.py INSTALLED_APPS = ( 'django.contrib.admin', ...
- 优化mybatis框架中的查询用户记录数的案例
通过对mybatis框架的中核心接口和类的分析,发现之前写的那个小demo是有问题的.现在对其进行部分优化. 如果存在多个功能的时候,势必会有很多重复的代码,如,创建sqlsession对象,关闭sq ...
- 开源项目(4-2)手势识别-Keras/Theano/OpenCV实现的CNN手势识别
https://github.com/asingh33/CNNGestureRecognizer 我提供了两种捕获模式: 二进制模式:在这里我首先将图像转换为灰度,然后应用高斯模糊效果和自适应阈值滤波 ...
- svn服务的安装与设置 .
1. 下载svn软件并安装,本人使用的是如下软件: TortoiseSVN-1.6.5.16974-win32-svn-1.6.5 Vis ...
- Xamarin.IOS/Mac开发中遇到的问题
虚拟机中安装的mac系统无法识别iphone 今天在 Xamarin.iOS 应用的免费预配 时,进行到 5.插入要在其中部署应用的 iOS 设备. 在第8选择iphone设备时,发现iphone并没 ...
- 微信小程序 movable-view组件应用:可拖动悬浮框_返回首页
1. movable-view组件具体内容可参考官网:微信官方文档 2. demo参考:https://github.com/ChinaFanny/YFWeappMovableView 运行效果 核心 ...
- 【大数据应用技术】作业十一|分布式并行计算MapReduce
本次作业在要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3319 1.用自己的话阐明Hadoop平台上HDFS和MapRe ...
- Spark2.x(五十四):在spark structured streaming下测试ds.selectExpr(),当返回列多时出现卡死问题。
业务需求,有一部分动态字段,需要在程序中动态加载并解析表达式: 实现方案1):在MapFunction.MapPartitionFunction中使用FelEngine进行解析: FelEngine ...
- [转]c++多线程编程之pthread线程深入理解
多线程编程之pthread线程深入理解 Pthread是 POSIX threads 的简称,是POSIX的线程标准. 前几篇博客已经能给你初步的多线程概念.在进一 ...