zoukankan      html  css  js  c++  java
  • 三、curator recipes之共享的可重入读写锁

    简介

    curator实现了跨JVM的可重入读写互斥锁。它使用zookeeper去进行加锁,所以指定相同路径的处理线程将会基于“公平锁”的机制去竞争锁资源。

    读写锁包含了读锁、写锁两个,它们的互斥关系如下:

    1)读写互斥;

    2)写写互斥;

    3)读读不互斥。

    重入性:读写锁是可以重入的,意味着你获取了一次读锁/写锁,那么你可以再次获取。但是要记得最后释放锁,获取了几次就得释放几次。

    降级/升级:写锁可以降级成读锁,但是读锁不能升级成写锁否则会导致循环等待最终死锁。

    官方文档:http://curator.apache.org/curator-recipes/shared-reentrant-read-write-lock.html

    javaDoc:http://curator.apache.org/apidocs/org/apache/curator/framework/recipes/locks/InterProcessReadWriteLock.html

    相关接口:InterProcessLock

    实现类:InterProcessReadWriteLock

    依赖

    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>2.12.0</version>
    </dependency>

    示例

    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 LocksDemo {
        private static CuratorFramework client;
        private static InterProcessMutex readLock;
        private static InterProcessMutex writeLock;
    
        static {
            client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181").retryPolicy(new ExponentialBackoffRetry(3000, 1)).build();
            // 调用启动
            client.start();
            // 获取读写锁
            InterProcessReadWriteLock lock = new InterProcessReadWriteLock(client, "/user");
            readLock = lock.readLock();
            writeLock = lock.writeLock();
        }
    
        public static void main(String[] args) throws Exception {
            new Thread(new Runnable() {
                public void run() {
                    System.out.println("线程1启动");
                    try {
                        // 先获取读锁
                        readLock.acquire();
                        System.out.println("获取读锁" + System.currentTimeMillis());
                        Thread.sleep(3000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            // 释放读锁
                            readLock.release();
                            System.out.println("释放读锁" + System.currentTimeMillis());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
            System.out.println("主线程休眠2秒,让子线程获取读锁");
            Thread.sleep(2000);
            // 争抢写锁,这时候读锁还没有释放
            writeLock.acquire();
            // 3秒钟以后,读锁释放了,写锁获取,最终写锁也释放
            System.out.println("获取写锁" + System.currentTimeMillis());
            writeLock.release();
            System.out.println("释放写锁" + System.currentTimeMillis());
            // 最后关闭
            client.close();
        }
    }

    我们先拿到一个framework,然后创建一个InterProcessReadWriteLock,就可以通过它拿到读写锁实例对象了。

    在代码中,子线程获取了读锁,然后休眠3秒,而主线程这期间想要获取写锁,就得阻塞等待读锁释放,然后才能获取写锁。

  • 相关阅读:
    基础抽象代数
    斜堆
    WC2018
    WC2019
    有向图上不相交路径计数
    生成树计数
    Pr&#252;fer序列
    反演
    1.1 Linux中的进程 --fork、孤儿进程、僵尸进程、文件共享分析
    Python程序的执行过程 解释型语言和编译型语言
  • 原文地址:https://www.cnblogs.com/lay2017/p/9635710.html
Copyright © 2011-2022 走看看