四、curator recipes之共享重入互斥锁
简介
curator的recipes实现了可重入互斥锁,允许你在分布式场景下多个进程之间实现锁的互斥以协调多进程执行。
相关类:InterProcessMutex
官方文档:http://curator.apache.org/curator-recipes/shared-reentrant-lock.html
javaDoc:http://curator.apache.org/apidocs/org/apache/curator/framework/recipes/locks/InterProcessMutex.html
依赖
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.1.0</version>
</dependency>
代码示例
以下代码,子线程先抢到了锁,而主线程进入阻塞。子线程5秒以后释放了锁,主线程这时候争抢到了锁,并最终释放锁。
对于互斥锁来说,只有一个线程能够持有,其它线程必须阻塞等待。
如果已经持有锁,又多次重入了,那么在释放的时候也得多次释放。
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry; public class MutexDemo { private static InterProcessMutex lock;
private static CuratorFramework client; static {
client = CuratorFrameworkFactory.newClient("localhost:2181", new ExponentialBackoffRetry(3000, 3));
lock = new InterProcessMutex(client, "/locks/0001");
client.start();
System.out.println("started");
} public static void main(String[] args) throws Exception {
new Thread(() -> {
try {
System.out.println("thread0 争抢锁");
lock.acquire();
System.out.println("thread0 抢到了锁,进入休眠");
Thread.sleep(5000);
System.out.println("thread0 结束休眠");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 当前线程获取到了锁
if (lock.isOwnedByCurrentThread()) {
lock.release();
}
System.out.println("thread0 释放了锁");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
// 休眠10毫秒,让子线程争抢到锁
Thread.sleep(10);
System.out.println("main 争抢锁");
lock.acquire();
System.out.println("main 抢到了锁");
lock.release();
System.out.println("main 释放了锁");
client.close();
}
}
注意:这里使用了isOwnedByCurrentThread,如果当前线程持有该锁,那么返回true,否则返回false。
它与isAcquiredInThisProcess的区别在于,isAcquiredInThisProcess只要当前JVM中有一个线程持有该锁就会返回true。
所以,如果采用isAcquiredInThisProcess来判断是否持有锁是错误的,除非你能保证程序中只会有一个线程来持有该锁。
四、curator recipes之共享重入互斥锁的更多相关文章
- 九、curator recipes之不可重入锁InterProcessSemaphoreMutex
简介 recipes的InterProcessSemaphoreMutex是一种不可重入的互斥锁,也就意味着即使是同一个线程也无法在持有锁的情况下再次获得锁,所以需要注意,不可重入的锁很容易在一些情况 ...
- Java并发包源码学习系列:ReentrantLock可重入独占锁详解
目录 基本用法介绍 继承体系 构造方法 state状态表示 获取锁 void lock()方法 NonfairSync FairSync 公平与非公平策略的差异 void lockInterrupti ...
- 线程执行synchronized同步代码块时再次重入该锁过程中抛异常,是否会释放锁
一个线程执行synchronized同步代码时,再次重入该锁过程中,如果抛出异常,会释放锁吗? 如果锁的计数器为1,抛出异常,会直接释放锁: 那如果锁的计数器为2,抛出异常,会直接释放锁吗? 来简单测 ...
- 可重入排他锁ReentrantLock源码浅析
1.引子 "ReentrantLock"单词中的“Reentrant”就是“重入”的意思,正如其名,ReentrantLock是一个支持重入的排他锁,即同一个线程中可以多次获得同步 ...
- 三、curator recipes之共享的可重入读写锁
简介 curator实现了跨JVM的可重入读写互斥锁.它使用zookeeper去进行加锁,所以指定相同路径的处理线程将会基于“公平锁”的机制去竞争锁资源. 读写锁包含了读锁.写锁两个,它们的互斥关系如 ...
- 【分布式锁】01-使用Redisson实现可重入分布式锁原理
前言 主流的分布式锁一般有三种实现方式: 数据库乐观锁 基于Redis的分布式锁 基于ZooKeeper的分布式锁 之前我在博客上写过关于mysql和redis实现分布式锁的具体方案:https:// ...
- redis 不可重入分布式锁(setNx()和getset()方法实现)
通常如果在单机环境,使用synchronized或juc ReentrantLock 实现锁机制,但如果是分布式系统,则需要借助第三方工具实现,比如redis.zookeeper等.redis为单进程 ...
- Java并发编程原理与实战十一:锁重入&自旋锁&死锁
一.锁重入 package com.roocon.thread.t6; public class Demo { /* 当第一个线程A拿到当前实例锁后,进入a方法,那么,线程A还能拿到被当前实例所加锁的 ...
- ReentrantReadWriteLock可重入,锁升级,锁降级
public class ReentrantReadWriteLockTest { public static void main(String[] args) throws InterruptedE ...
随机推荐
- Remoteland HDU - 4196
题意: 给出一个n,在[1, n] 中挑选几个不同的数相乘,求能的到的最大完全平方数 解析: 最大的肯定是n!, 然后n!不一定是完全平方数 (我们知道一个完全平方数,质因子分解后,所有质因子的质数均 ...
- 《快学Scala》第六章 对象 第七章 包和引入
- 给 console 添加颜色
简评:使用 %c 声明可以给 console 的输出添加 CSS 样式,日志太多的话,给不同种类的日志设置不同的样式,可以极大的提升阅读体验. 什么是 %c %c: 标识将 CSS 样式应用于 %c ...
- Python中的匿名函数lambda的用法
一.lambda函数的简介 对lambda函数,它其实是一个类似于def的函数,只不过lambda是一个不需要定义函数名的匿名函数.当我们在有些时候,需要做一些简单的数学计算时,如果定义一个def函 ...
- Java方法区
方法区 在一个jvm实例的内部,类型信息被存储在一个称为方法区的内存逻辑区中.类型信息是由类加载器在类加载时从类文件中提取出来的.类(静态)变量也存储在方法区中. jvm实现的设计者决定了类型信息的内 ...
- jmeter的non-gui模式的使用
jmeter的non-gui模式的使用,待补充
- linux 将进程或者线程绑定到指定的cpu上
基本概念 cpu亲和性(affinity) CPU的亲和性, 就是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器,也称为CPU关联性:再简单的点的描述就将指定的进程或线程绑定到相应的 ...
- ReactNative常用组件库 react-native-camera 相机
通过react-native-camera调用原生相机,及自定义样式 GitHub地址: https://github.com/react-native-community/react-native- ...
- 【EF数据库链接报错】“The underlying provider failed on open”
EF在操作数据库时要反复链接.断开数据库,如果连接字符串是windows 服务验证,而不是用的用户名和密码,那么尝试访问数据库的用户是NT AUTHORITY\NETWORK SERVICE.权限不够 ...
- JAVA编程思想第一章——对象导论