使用ZooKeeper实现Java跨JVM的分布式锁(读写锁)
二、使用ZooKeeper实现Java跨JVM的分布式锁(优化构思)
三、使用ZooKeeper实现Java跨JVM的分布式锁(读写锁)
读写锁:
本文在前面俩片的基础之上介绍如何 使用ZooKeeper实现Java跨JVM的分布式锁(读写锁)。
简单介绍一下读写锁,在使用读写锁时, 多个客户端(线程)可以同时获取 “读锁”, 但是“写入锁”是排它的,只能单独获取。
1、假设A,B线程获取到 “读锁”, 这时C线程就不能获取 “写锁”。
2、假设C线程获取了“写锁”,那么A,B线程就不能获取“读锁”。
这在某种情况下会大幅度提高系统的性能,在单JVM进程内 Java已经提供了这种锁的机制,可以参考ReentrantReadWriteLock这个类。
基于ZK的分布式读写锁:
本文主要介绍ZK的分布式读写锁,还是基于Curator客户端实现。
- package com.framework.code.demo.zook.lock;
- import org.apache.curator.RetryPolicy;
- import org.apache.curator.framework.CuratorFramework;
- import org.apache.curator.framework.CuratorFrameworkFactory;
- import org.apache.curator.framework.recipes.locks.InterProcessMutex;
- import org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
- import org.apache.curator.retry.ExponentialBackoffRetry;
- public class ReadWriteLock {
- /**
- * @param args
- * @throws Exception
- */
- public static void main(String[] args) throws Exception {
- RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
- CuratorFramework client = CuratorFrameworkFactory
- .newClient("192.168.1.103:2181", retryPolicy);
- client.start();
- InterProcessReadWriteLock readWriteLock = new InterProcessReadWriteLock(client, "/read-write-lock");
- //读锁
- final InterProcessMutex readLock = readWriteLock.readLock();
- //写锁
- final InterProcessMutex writeLock = readWriteLock.writeLock();
- try {
- readLock.acquire();
- System.out.println(Thread.currentThread() + "获取到读锁");
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- //在读锁没释放之前不能读取写锁。
- writeLock.acquire();
- System.out.println(Thread.currentThread() + "获取到写锁");
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- writeLock.release();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }).start();
- //停顿3000毫秒不释放锁,这时其它线程可以获取读锁,却不能获取写锁。
- Thread.sleep(3000);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- readLock.release();
- }
- Thread.sleep(1000000);
- client.close();
- }
- }
实现原理:
实现原理与之前介绍的锁的原理基本类似,这里主要说明一下不同之处。
1、写入锁在申请锁时写入的节点名称是这样的 xxxx-__WRIT__00000000xxx 例如: _c_9b6e456b-94fe-47e7-b968-34027c094b7d-__WRIT__0000000006
2、读取锁在申请锁时写入的节点名称是这样的 xxxx-__READ__00000000xxx 例如: _c_9b6e456b90-9c33-6294665cf525--b6448-__READ__0000000005
区别就是写入锁的字符串包含WRIT,读取所包含READ
获取锁的区别:
1、写入锁在获取锁时的处理与前面文章介绍的原理一直,就是判断自己前面还有没有节点,如果没有就可以获取到锁,如果有就等待前面的节点释放锁。
2、读取锁在获取锁时的处理是,判断自己前面还有没有写入锁的节点,也就是前面的节点是否包含WRIT,如果有那么等待前面的节点释放锁。
读取所自己前面有 其它 读取锁节点 无所谓,它仍然可以获取到锁,这也就是读取所可以多客户端共享的原因。
使用ZooKeeper实现Java跨JVM的分布式锁(读写锁)的更多相关文章
- 使用ZooKeeper实现Java跨JVM的分布式锁(优化构思)
一.使用ZooKeeper实现Java跨JVM的分布式锁 二.使用ZooKeeper实现Java跨JVM的分布式锁(优化构思) 三.使用ZooKeeper实现Java跨JVM的分布式锁(读写锁) 说明 ...
- 使用ZooKeeper实现Java跨JVM的分布式锁
一.使用ZooKeeper实现Java跨JVM的分布式锁 二.使用ZooKeeper实现Java跨JVM的分布式锁(优化构思) 三.使用ZooKeeper实现Java跨JVM的分布式锁(读写锁) 说明 ...
- Java使用Redis实现分布式锁来防止重复提交问题
如何用消息系统避免分布式事务? - 少年阿宾 - BlogJavahttp://www.blogjava.net/stevenjohn/archive/2018/01/04/433004.html [ ...
- Java并发-显式锁篇【可重入锁+读写锁】
作者:汤圆 个人博客:javalover.cc 前言 在前面并发的开篇,我们介绍过内置锁synchronized: 这节我们再介绍下显式锁Lock 显式锁包括:可重入锁ReentrantLock.读写 ...
- zookeeper笔记之基于zk实现分布式锁
一.分布式锁概述 Java中基于AQS框架提供了一系列的锁,但是当需要在集群中的多台机器上互斥执行一段代码或使用资源时Java提供的这种单机锁就没了用武之地,此时需要使用分布式锁协调它们.分布式锁有很 ...
- ZooKeeper(八)-- Curator实现分布式锁
1.pom.xml <dependencies> <dependency> <groupId>junit</groupId> <artifactI ...
- Java基于redis实现分布式锁(SpringBoot)
前言 分布式锁,其实原理是就是多台机器,去争抢一个资源,谁争抢成功,那么谁就持有了这把锁,然后去执行后续的业务逻辑,执行完毕后,把锁释放掉. 可以通过多种途径实现分布式锁,例如利用数据库(mysql等 ...
- java中redis的分布式锁工具类
使用方式 try { if(PublicLock.getLock(lockKey)){ //这里写代码逻辑,执行完后需要释放锁 PublicLock.freeLock(lockKey); } } ca ...
- java基础之----redi分布式锁
最近项目中,用到了redis分布式锁,使用过程有些心得,所以希望分享给大家. 首先我们意识里要知道分布锁有哪些? 分布式锁一般分三种,基于数据库的乐观锁,基于redis的分布式锁,基于zookeper ...
随机推荐
- Python设计模式-装饰器模式
装饰器模式 装饰器模式,动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活. 代码示例 #coding:utf-8 #装饰器模式 class Beverage(): ...
- oradebug工具使用(转载)
在之前的HangAnalyze 中有使用oradebug命令,在这篇文章里,我们主要是重点看一下这个oradebug命令: Oracle HANGANALYZE 功能诊断 DB hanging htt ...
- Linux常用命令(6/26)——dd命令和split命令
dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 以可选块长度复制文件,默认情况下从标准输入设备输出到标准输出设备.复制过程中,还可以对文件进行一些转换. dd命令可以指定block的 ...
- json字符串转化为json对象and 对象转化为 json字符串
第一种方法: var data =evel('('+jsonstr+')') 解析: 这种方法是常用的方法, 即动态执行 javascript代码 在堆中存放数据. 存在安全问题. 第二种方法: ...
- 在线修改GTID模式
在线修改GTID模式 1. 在每一台机器上执行命令 SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN; 这是很重要的一步,必须确保服务器上没有违反GTID规范的 ...
- winrar5.0注册码
新建一个文本文档,输入横线内的内容 ---------------------------------------------------------------------------------- ...
- GRE/GMAT/LSAT长难句300例精讲精练-思维导图
<GRE/GMAT/LSAT长难句300例精讲精练>是GRE超人气名师陈琦老师团队的又一本新作,也是“再要你命3000”的新成员,从之前的词汇.短语.练习,提升到长难句层面,相信学完本书后 ...
- 《Maven实战》第10章 使用Maven进行测试
10.2maven-surefire-plugin插件 [生命周期]的[阶段]与[插件]的[目标]绑定 default生命周期的test阶段:使用单元测试框架运行测试 Maven内置绑定:defaul ...
- Curator学习
Curator是对zookeeper的高级封装. 考虑到使用它来开发zookeeper应用的方便,特此来记录总结学习与开发使用过程的问题. 1. curator-framework Curator F ...
- 在 CentOS 7.0 上安装配置 Ceph 存储
来自: https://linux.cn/article-6624-1.html Ceph 是一个将数据存储在单一分布式计算机集群上的开源软件平台.当你计划构建一个云时,你首先需要决定如何实现你的存储 ...