一、使用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客户端实现。

  1. package com.framework.code.demo.zook.lock;
  2. import org.apache.curator.RetryPolicy;
  3. import org.apache.curator.framework.CuratorFramework;
  4. import org.apache.curator.framework.CuratorFrameworkFactory;
  5. import org.apache.curator.framework.recipes.locks.InterProcessMutex;
  6. import org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
  7. import org.apache.curator.retry.ExponentialBackoffRetry;
  8. public class ReadWriteLock {
  9. /**
  10. * @param args
  11. * @throws Exception
  12. */
  13. public static void main(String[] args) throws Exception {
  14. RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
  15. CuratorFramework client = CuratorFrameworkFactory
  16. .newClient("192.168.1.103:2181", retryPolicy);
  17. client.start();
  18. InterProcessReadWriteLock readWriteLock = new InterProcessReadWriteLock(client, "/read-write-lock");
  19. //读锁
  20. final InterProcessMutex readLock = readWriteLock.readLock();
  21. //写锁
  22. final InterProcessMutex writeLock = readWriteLock.writeLock();
  23. try {
  24. readLock.acquire();
  25. System.out.println(Thread.currentThread() + "获取到读锁");
  26. new Thread(new Runnable() {
  27. @Override
  28. public void run() {
  29. try {
  30. //在读锁没释放之前不能读取写锁。
  31. writeLock.acquire();
  32. System.out.println(Thread.currentThread() + "获取到写锁");
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. } finally {
  36. try {
  37. writeLock.release();
  38. } catch (Exception e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. }
  43. }).start();
  44. //停顿3000毫秒不释放锁,这时其它线程可以获取读锁,却不能获取写锁。
  45. Thread.sleep(3000);
  46. } catch (Exception e) {
  47. e.printStackTrace();
  48. } finally {
  49. readLock.release();
  50. }
  51. Thread.sleep(1000000);
  52. client.close();
  53. }
  54. }

 

实现原理:

实现原理与之前介绍的锁的原理基本类似,这里主要说明一下不同之处。

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的分布式锁(读写锁)的更多相关文章

  1. 使用ZooKeeper实现Java跨JVM的分布式锁(优化构思)

    一.使用ZooKeeper实现Java跨JVM的分布式锁 二.使用ZooKeeper实现Java跨JVM的分布式锁(优化构思) 三.使用ZooKeeper实现Java跨JVM的分布式锁(读写锁) 说明 ...

  2. 使用ZooKeeper实现Java跨JVM的分布式锁

    一.使用ZooKeeper实现Java跨JVM的分布式锁 二.使用ZooKeeper实现Java跨JVM的分布式锁(优化构思) 三.使用ZooKeeper实现Java跨JVM的分布式锁(读写锁) 说明 ...

  3. Java使用Redis实现分布式锁来防止重复提交问题

    如何用消息系统避免分布式事务? - 少年阿宾 - BlogJavahttp://www.blogjava.net/stevenjohn/archive/2018/01/04/433004.html [ ...

  4. Java并发-显式锁篇【可重入锁+读写锁】

    作者:汤圆 个人博客:javalover.cc 前言 在前面并发的开篇,我们介绍过内置锁synchronized: 这节我们再介绍下显式锁Lock 显式锁包括:可重入锁ReentrantLock.读写 ...

  5. zookeeper笔记之基于zk实现分布式锁

    一.分布式锁概述 Java中基于AQS框架提供了一系列的锁,但是当需要在集群中的多台机器上互斥执行一段代码或使用资源时Java提供的这种单机锁就没了用武之地,此时需要使用分布式锁协调它们.分布式锁有很 ...

  6. ZooKeeper(八)-- Curator实现分布式锁

    1.pom.xml <dependencies> <dependency> <groupId>junit</groupId> <artifactI ...

  7. Java基于redis实现分布式锁(SpringBoot)

    前言 分布式锁,其实原理是就是多台机器,去争抢一个资源,谁争抢成功,那么谁就持有了这把锁,然后去执行后续的业务逻辑,执行完毕后,把锁释放掉. 可以通过多种途径实现分布式锁,例如利用数据库(mysql等 ...

  8. java中redis的分布式锁工具类

    使用方式 try { if(PublicLock.getLock(lockKey)){ //这里写代码逻辑,执行完后需要释放锁 PublicLock.freeLock(lockKey); } } ca ...

  9. java基础之----redi分布式锁

    最近项目中,用到了redis分布式锁,使用过程有些心得,所以希望分享给大家. 首先我们意识里要知道分布锁有哪些? 分布式锁一般分三种,基于数据库的乐观锁,基于redis的分布式锁,基于zookeper ...

随机推荐

  1. Redis2.8配置文件详解(转)

    add by zhj : 没找到本文的原文.另外,redis配置文件中文翻译 也翻译的不错,可以与本文对照看.两篇文章都是以Redis2.8来介绍的 在Redis中直接启动redis-server服务 ...

  2. Python游戏引擎开发(五):Sprite精灵类和鼠标事件

    本次来实现Sprite类和鼠标事件. 说起这个Sprite啊,涉及过2D游戏研究领域的看官应该都听说过它. 它中文原意是"精灵",只是在不同人的眼中,它所表示的意义不同. 比方说在 ...

  3. Angular学习笔记—Rxjs、Promise的区别

    Promises: 异步操作完成或失败时处理单个事件 不可取消 代码可读性强,有try/catch Observables: 可持续监听和响应多个事件 可取消订阅 支持map, filter, red ...

  4. JS操作时间 - UNIX时间戳简单介绍

    准备知识 GMT(Greenwich Mean Time) - 格林尼治时间.UTC(Universal Time Code) - 国际协调时间.PST(Pacific Standard Time,太 ...

  5. 关于mysql主从复制的概述与分类

    一.概述: 按照MySQL的同步复制特点,大体上可以分为三种类别: 1.异步复制: 2.半同步复制: 3.完全同步的复制: -------------------------------------- ...

  6. Maven项目settings.xml的配置

    原文地址 http://www.cnblogs.com/DreamDrive/p/5571916.html 在Maven中提供了一个settings.xml文件来定义Maven的全局环境信息.这个文件 ...

  7. Django 之基础学习

     阅读目录 配置 视图层之路由系统配置 模版层 模版过滤器 request & response Ajax Cookie Session 分页 文件传输 Django MTV模型 Django ...

  8. HDOJ 1423 Greatest Common Increasing Subsequence 【DP】【最长公共上升子序列】

    HDOJ 1423 Greatest Common Increasing Subsequence [DP][最长公共上升子序列] Time Limit: 2000/1000 MS (Java/Othe ...

  9. Codeforces Round #395 (Div. 2) C. Timofey and a tree

    地址:http://codeforces.com/contest/764/problem/C 题目: C. Timofey and a tree time limit per test 2 secon ...

  10. ZOJ - 3593 One Person Game (扩展欧几里得)

    题意:一个人在坐标A,要前往坐标B的位置.可以往左或往右走a,b,a+b个单位,求到达B的最小步数. 分析:扩展欧几里得算法求解线性方程的套路不变.令C=fabs(A-B),c = a+b, 扩展gc ...