Curator链接zookeeper实现分布式锁

来源:互联网 发布:天津密云路五金城淘宝 编辑:程序博客网 时间:2024/05/30 02:52

curator的特性,不必多说,可以说是 curator是zookeeper中的类似于guava对于java的意义一样,提供了丰富的封装,异常处理,提供了fluent编程模型,提供了master选举,分布式锁,分布式基数,分布式barrier,可以很方便的为日常生产所使用。

 这次主要用了curator的InterProcessMutex这种互斥锁来做,也借于此机会,阅读了它的代码,分享一下它的机制,共大家一起来交流学习下。

第一步:首先需要在pom中引入依赖的jar:

        <dependency>            <groupId>org.apache.zookeeper</groupId>            <artifactId>zookeeper</artifactId>            <version>3.4.9</version>        </dependency>        <!--curator-->        <dependency>            <groupId>org.apache.curator</groupId>            <artifactId>curator-framework</artifactId>            <version>2.12.0</version>        </dependency>        <dependency>            <groupId>org.apache.curator</groupId>            <artifactId>curator-recipes</artifactId>            <version>2.12.0</version>        </dependency>

第二步:创建一个zookeeper链接的维护类:

@Setter@Getterpublic class TestingServer implements Closeable {    private String connectString;    public TestingServer(){        this.connectString = "10.7.28.179:2181,10.7.28.180:2181,10.7.28.181:2181";    }    @Override    public void close() throws IOException {        System.out.println("关闭连接");    }}

第三步:共享资源处理类,每次只期望单线程访问,否则会有并发问题

public class FakeLimitedResource {    private final AtomicBoolean inUse = new AtomicBoolean(false);    public void use() throws InterruptedException {        // 真实环境中我们会在这里访问/维护一个共享的资源        //这个例子在使用锁的情况下不会非法并发异常IllegalStateException        //但是在无锁的情况由于sleep了一段时间,很容易抛出异常        if (!inUse.compareAndSet(false, true)) {            throw new IllegalStateException("Needs to be used by one client at a time");        }        try {            Thread.sleep((long) (3 * Math.random()));        } finally {            inUse.set(false);        }    }}
第四步:封装了zookeeper锁的工具类
/** * Created by Administrator on 2017/9/8. * 封装了zookeeper锁的工具类 */public class ExampleClientThatLocks {    private final InterProcessMutex lock;    //封装定义了资源的处理类    private final FakeLimitedResource resource;    private final String clientName;    public ExampleClientThatLocks(CuratorFramework client, String lockPath, FakeLimitedResource resource, String clientName) {        this.resource = resource;        this.clientName = clientName;        lock = new InterProcessMutex(client, lockPath);    }    /**     * 线程进来获取锁,释放锁的方法     * @param time     * @param unit     * @throws Exception     */    public void doWork(long time, TimeUnit unit) throws Exception {        //线程阻塞等待锁的超时时间为time,如果时间超过时间限制则lock.acquire()返回false,抛出等待锁失败的异常        if (!lock.acquire(time, unit)) {            throw new IllegalStateException(clientName + " could not acquire the lock");        }        try {            System.out.println(clientName + " has the lock");            resource.use(); //access resource exclusively        } finally {            System.out.println(clientName + " releasing the lock");            lock.release(); // always release the lock in a finally block        }    }}

第五步:创建测试类同时启动100个线程去竞争锁:

/** * Created by Administrator on 2017/9/8. * 重入锁测试类 */public class InterProcessMutexExample {    //同时启动100个线程去竞争共享资源    private static final int QTY = 100;    private static final String PATH = "/examples/locks";    public static void main(String[] args) throws Exception {        FakeLimitedResource resource = new FakeLimitedResource();        ExecutorService service = Executors.newFixedThreadPool(QTY);        final TestingServer server = new TestingServer();        try {            for (int i = 0; i < QTY; ++i) {                final int index = i;                Callable<Void> task = new Callable<Void>() {                    @Override                    public Void call() throws Exception {                        CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(1000, 3));                        try {                            client.start();                            final ExampleClientThatLocks example = new ExampleClientThatLocks(client, PATH, resource, "Client " + index);                            example.doWork(1, TimeUnit.SECONDS);                        } catch (Throwable e) {                            e.printStackTrace();                        } finally {                            CloseableUtils.closeQuietly(client);                        }                        return null;                    }                };                service.submit(task);            }            service.shutdown();            service.awaitTermination(10, TimeUnit.MINUTES);        } finally {            CloseableUtils.closeQuietly(server);        }    }}
贴出部分执行结果如下所示:

Client 10 has the lockClient 10 releasing the lockClient 38 has the lockClient 38 releasing the lockClient 97 has the lockClient 97 releasing the lockClient 76 has the lockClient 76 releasing the lockClient 50 has the lockClient 50 releasing the lockClient 34 has the lockClient 34 releasing the lockClient 33 has the lockClient 33 releasing the lockClient 2 has the lockClient 2 releasing the lockClient 78 has the lockClient 78 releasing the lockClient 18 has the lockClient 18 releasing the lockClient 49 has the lockClient 49 releasing the lockClient 82 has the lockClient 82 releasing the lockClient 77 has the lockClient 77 releasing the lockClient 51 has the lockClient 51 releasing the lock



参考资料:http://www.jianshu.com/p/70151fc0ef5d

Curator深入使用:http://www.cnblogs.com/LiZhiW/p/4926385.html



原创粉丝点击