• 使用ZooKeeper实现Java跨JVM的分布式锁(读写锁)


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

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


     

    实现原理:

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

    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,如果有那么等待前面的节点释放锁。

    读取所自己前面有 其它 读取锁节点 无所谓,它仍然可以获取到锁,这也就是读取所可以多客户端共享的原因。

  • 相关阅读:
    caffe的python接口学习(5):生成deploy文件
    Flutter -------- 新手 WanAndroid 项目练习
    android -------- GifView 显示gif图片
    android -------- java.net.UnknownServiceException
    Flutter ------- WebView加载网页
    Flutter -------- 解析JSON数据
    Flutter -------- Http库 网络请求封装(HttpController)
    android ------ 实现高德定位并获取相应信息 ( 最新版高德SDK 和 Android SDK版本)
    Flutter -------- dio网络请求
    Flutter -------- Http库实现网络请求
  • 原文地址:https://www.cnblogs.com/hujihon/p/6826771.html
Copyright © 2020-2023  润新知