Java限制可以重入次数的锁
完全 模仿ReentrantLock, 通过继承 java.util.concurrent.locks.Lock , 内置 AbstractQueuedSynchronizer 实现类,限制可以重入次数的锁。
这个其实不难, 只要稍微注意一点就好了
ReenterLimitedLock 关键实现:
/**
* l.k
*
* 限制可以重入次数的锁,默认是2次
*
*/
public class ReenterLimitedLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = 7373984872572414699L;
private final Sync sync; /**
* Creates an instance of {@code ReenterLimitedLock}.
* This is equivalent to using {@code ReenterLimitedLock(false)}.
*/
public ReenterLimitedLock() {
sync = new NonfairSync(2);
} public ReenterLimitedLock(int reenterLimit) {
sync = new NonfairSync(reenterLimit);
} public ReenterLimitedLock(boolean fair, int reenterLimit) {
sync = fair ? new FairSync(reenterLimit) : new NonfairSync(reenterLimit);
} public ReenterLimitedLock(boolean fair) {
sync = fair ? new FairSync(2) : new NonfairSync(2);
} abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
private boolean exceeded;
private int reenterLimit; public Sync(int reenterLimit) {
this.reenterLimit = reenterLimit;
} abstract void lock(); final boolean nonfairTryAcquire(int acquires) throws MaximumLockCountExceededException {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
// if (nextc < 0) // overflow
if (nextc > reenterLimit) { // 关键
exceeded = true;
// return false;
// throw new IllegalStateException("Maximum lock count exceeded" + 2);
throw new MaximumLockCountExceededException(reenterLimit);
}
setState(nextc);
return true;
}
return false;
} protected final boolean tryRelease(int releases) {
if (isExceeded()) {
return false;
}
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
} protected final boolean isHeldExclusively() {
// While we must in general read state before owner,
// we don't need to do so to check if current thread is owner
return getExclusiveOwnerThread() == Thread.currentThread();
} final ConditionObject newCondition() {
return new ConditionObject();
} // Methods relayed from outer class final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
} final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
} final boolean isLocked() {
return getState() != 0;
} /**
* Reconstitutes the instance from a stream (that is, deserializes it).
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0); // reset to unlocked state
} public boolean isExceeded() {
return exceeded;
} public void setExceeded(boolean exceeded) {
this.exceeded = exceeded;
} public int getReenterLimit() {
return reenterLimit;
} public void setReenterLimit(int reenterLimit) {
this.reenterLimit = reenterLimit;
} } /**
* Sync object for non-fair locks
*/
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L; public NonfairSync(int reenterLimit) {
super(reenterLimit);
} /**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
} protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
} /**
* Sync object for fair locks
*/
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L; public FairSync(int reenterLimit) {
super(reenterLimit);
} final void lock() {
acquire(1);
} /**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
// if (nextc < 0)
if (nextc > getReenterLimit()) // 这里是关键
throw new MaximumLockCountExceededException(getReenterLimit());
// throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
} public void lock() {
sync.lock();
} public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
} public boolean tryLock() {
return sync.nonfairTryAcquire(1);
} public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
} public void unlock() {
sync.release(1);
} public Condition newCondition() {
return sync.newCondition();
} public int getHoldCount() {
return sync.getHoldCount();
} public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
} public boolean isLocked() {
return sync.isLocked();
} public final boolean isFair() {
return sync instanceof FairSync;
} protected Thread getOwner() {
return sync.getOwner();
} public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
} public final boolean hasQueuedThread(Thread thread) {
return sync.isQueued(thread);
} public final int getQueueLength() {
return sync.getQueueLength();
} protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
} public boolean hasWaiters(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
} public int getWaitQueueLength(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
} protected Collection<Thread> getWaitingThreads(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
} public String toString() {
Thread o = sync.getOwner();
return super.toString() + ((o == null) ?
"[Unlocked]" :
"[Locked by thread " + o.getName() + "]");
}
}
MaximumLockCountExceededException 异常:
public class MaximumLockCountExceededException extends IllegalStateException {
//public class MaximumLockCountExceededException extends Exception {
public MaximumLockCountExceededException(String s) {
super(s);
}
public MaximumLockCountExceededException(int n) {
super("Maximum lock count exceeded: " + n);
}
}
测试:
/**
* Created by L.k on 2018/11/29.
*/
public class Testaa { ReenterLimitedLock twiceLock = new ReenterLimitedLock(); public static void main(String[] args) {
ReenterLimitedLock twiceLock = new ReenterLimitedLock();
Testaa testaa = new Testaa(twiceLock);
testaa.aa("asf");
} public Testaa(ReenterLimitedLock twiceLock) {
this.twiceLock = twiceLock;
} public void aa(String aa) {
try {
twiceLock.lock();
Thread.sleep(1000);
System.out.println("aa = [" + aa + "]");
bb(aa);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
twiceLock.unlock();
}
} public void bb(String bb) {
try {
twiceLock.lock();
Thread.sleep(1000); System.out.println("bb = [" + bb + "]"); cc(bb); System.out.println("Testaa.bb"); } catch (InterruptedException e) {
e.printStackTrace();
} finally {
twiceLock.unlock();
}
} public void cc(String cc) {
try {
twiceLock.lock();
Thread.sleep(1000); System.out.println("cc = [" + cc + "]"); } catch (InterruptedException e) {
e.printStackTrace();
// } catch (InterruptedException | IllegalStateException e) {
} catch (MaximumLockCountExceededException e) { // 这里必须要 捕获 MaximumLockCountExceededException, 否则 bb 方法也会异常退出
// e.printStackTrace();
System.out.println("xxxx IllegalStateException = " + e);
} finally {
twiceLock.unlock();
}
}
}
Java限制可以重入次数的锁的更多相关文章
- Java并发包源码学习系列:ReentrantLock可重入独占锁详解
目录 基本用法介绍 继承体系 构造方法 state状态表示 获取锁 void lock()方法 NonfairSync FairSync 公平与非公平策略的差异 void lockInterrupti ...
- java多线程系类:JUC锁:01之框架
本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下:01. Java多线程系列--"JUC锁"01之 框架02. Java多线程系列--"JUC锁&q ...
- Java多线程总结(二)锁、线程池
掌握Java中的多线程,必须掌握Java中的各种锁,以及了解Java中线程池的运用.关于Java多线程基础总结可以参考我的这篇博文Java多线程总结(一)多线程基础 转载请注明出处——http://w ...
- Java 线程 — synchronized、volatile、锁
线程同步基础 synchronized 和volatile是Java线程同步的基础. synchronized 将临界区的内容上锁,同一时刻只有一个进程能访问该临界区代码 使用的是内置锁,锁一个时刻只 ...
- Java并发编程之显式锁机制
我们之前介绍过synchronized关键字实现程序的原子性操作,它的内部也是一种加锁和解锁机制,是一种声明式的编程方式,我们只需要对方法或者代码块进行声明,Java内部帮我们在调用方法之前和结束时加 ...
- Java多线程与并发模型之锁
这是一篇总结Java多线程开发的长文.文章是从Java创建之初就存在的synchronized关键字引入,对Java多线程和并发模型进行了探讨.希望通过此篇内容的解读能帮助Java开发者更好的理清Ja ...
- Java并发包——线程同步和锁
Java并发包——线程同步和锁 摘要:本文主要学习了Java并发包里有关线程同步的类和锁的一些相关概念. 部分内容来自以下博客: https://www.cnblogs.com/dolphin0520 ...
- 死磕 java同步系列之zookeeper分布式锁
问题 (1)zookeeper如何实现分布式锁? (2)zookeeper分布式锁有哪些优点? (3)zookeeper分布式锁有哪些缺点? 简介 zooKeeper是一个分布式的,开放源码的分布式应 ...
- 死磕 java同步系列之redis分布式锁进化史
问题 (1)redis如何实现分布式锁? (2)redis分布式锁有哪些优点? (3)redis分布式锁有哪些缺点? (4)redis实现分布式锁有没有现成的轮子可以使用? 简介 Redis(全称:R ...
随机推荐
- LinuxTimeLine
- Kerberos主从配置文档
Kerberos主从配置文档 1. Kerberos主从同步机制 在Master上通过以下命令同步数据: kdb5_util dump /var/kerberos/krb5kdc/slave_db ...
- Unable to load DLL 'api-ms-win-core-localization-l1-2-0.dll': 找不到指定的模块
asp.net mvc 4.6 发布到WinServer2008R2 SP1 提示 错误 Unable to load DLL 'api-ms-win-core-localization-l1-2-0 ...
- 扫描工具——Nmap用法详解
Nmap使用 Nmap是主机扫描工具,他的图形化界面是Zenmap,分布式框架为Dnamp. Nmap可以完成以下任务: 主机探测 端口扫描 版本检测 系统检测 支持探测脚本的编写 Nmap在实际中应 ...
- 异常处理:try - except 和 try finally。
异常处理:try-except语句 1) 此处:as reason为可选参数,reason是一个变量. 2) 使用try—except语句时,检测范围内出现错误,不会有红色的报错提 ...
- ArcGIS 按多边形区域统计栅格影像的一些信息
在使用ArcGIS对栅格影像进行分析时,难免要进行一些统计类的分析.如统计框选区域的像素的个数,面积.均值等内容. 下面给出使用“Spatial Analyst Tools -- > Zonal ...
- escu问题及解决
************************************************************** Qt 出现“undefined reference to `vtable ...
- 类Shiro权限校验框架的设计和实现(2)--对复杂权限表达式的支持
前言: 我看了下shiro好像默认不支持复杂表达式的权限校验, 它需要开发者自己去做些功能扩展的工作. 针对这个问题, 同时也会为了弥补上一篇文章提到的支持复杂表示需求, 特地尝试写一下解决方法. 本 ...
- python学习之路08——元组、集合
一. 元组 1.概念 列表:是一种有序的集合 元组和列表的区别: a.列表:[] 元组:() b.列表中的元素可以进行增加和删除操作,但是,元组中的元素不能进行修改 c.相同点:都是一种容 ...
- ViewpagerHandler
import android.os.AsyncTask; import android.os.Handler; import android.os.Message; import android.su ...