<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.study</groupId>
<artifactId>curator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>curator</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
package com.study.curator;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
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.retry.ExponentialBackoffRetry;
//分布式的锁全局同步, 这意味着任何一个时间点不会有两个客户端都拥有相同的锁
public class TestCuratorLock {
public static void main(String[] args) throws InterruptedException {
//CountDownLatch一种同步帮助,允许一个或多个线程等待直到一组正在执行的操作线程完成。
//在线程可以通过等待之前,必须调用的时间倒计时的次数
CountDownLatch latch = new CountDownLatch(5);
String zookeeperConnectionString = "hadoop:2181,hadoop1:2182,hadoop2:2182";
//重新链接策略的抽象;1000毫秒重试间隔,3次重试
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
//使用newClient方式创建Zookeeper Client
CuratorFramework client = CuratorFrameworkFactory.newClient(
zookeeperConnectionString, retryPolicy);
client.start();
System.out.println("客户端启动。。。。");
//执行器,提供管理多个异步Task运行的方法和终止,生成一个Future来跟踪Task
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
//提交一个runnable任务,执行并返回一个Future,Future描述任务结果
//如果任务成功完成,Future的get方法返回null
exec.submit(new MyLock("client" + i, client, latch));
}
exec.shutdown();
//导致当前线程等待直到锁存器已计数到零,除非线程被中断
latch.await();
System.out.println("所有任务执行完毕");
client.close();
System.out.println("客户端关闭。。。。");
}
static class MyLock implements Runnable {
private String name;
private CuratorFramework client;
private CountDownLatch latch;
public MyLock(String name, CuratorFramework client, CountDownLatch latch) {
this.name = name;
this.client = client;
this.latch = latch;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void run() {
//InterProcessMutex:全局可重入的锁(Shared Reentrant Lock)的实现;
//Shared意味着锁是全局可见的, 客户端都可以请求锁
//Reentrant和JDK的ReentrantLock类似,意味着同一个客户端在拥有锁的同时,可以多次获取,不会被阻塞。
InterProcessMutex lock = new InterProcessMutex(client,
"/test_group");
try {
//通过acquire获得锁,并提供超时机制:
if (lock.acquire(120, TimeUnit.SECONDS)) {
try {
System.out.println("----------" + this.name
+ "获得资源----------");
System.out.println("----------" + this.name
+ "正在处理资源----------");
Thread.sleep(10 * 1000);
System.out.println("----------" + this.name
+ "资源使用完毕----------");
latch.countDown();
} finally {
//通过release()方法释放锁。
//InterProcessMutex 实例可以重用。
lock.release();
System.out.println("----------" + this.name
+ "释放----------");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
执行同时进入zkCli命令行,查看.一下是部分内容
[zk: localhost:2181(CONNECTED) 5] ls /test_group
[_c_3b8229b5-d116-4588-befd-3eed639cce4f-lock-0000000003, _c_7d5b30d7-73ef-4739-9686-bb008fa4b7f7-lock-0000000004]
[zk: localhost:2181(CONNECTED) 6] ls /test_group
[_c_3b8229b5-d116-4588-befd-3eed639cce4f-lock-0000000003, _c_7d5b30d7-73ef-4739-9686-bb008fa4b7f7-lock-0000000004]
[zk: localhost:2181(CONNECTED) 7] ls /test_group
[_c_7d5b30d7-73ef-4739-9686-bb008fa4b7f7-lock-0000000004]
[zk: localhost:2181(CONNECTED) 8] ls /test_group
[]
eclipse控制台输出如下:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
客户端启动。。。。
----------client3获得资源----------
----------client3正在处理资源----------
----------client3资源使用完毕----------
----------client3释放----------
----------client1获得资源----------
----------client1正在处理资源----------
----------client1资源使用完毕----------
----------client1释放----------
----------client4获得资源----------
----------client4正在处理资源----------
----------client4资源使用完毕----------
----------client4释放----------
----------client2获得资源----------
----------client2正在处理资源----------
----------client2资源使用完毕----------
----------client2释放----------
----------client0获得资源----------
----------client0正在处理资源----------
----------client0资源使用完毕----------
所有任务执行完毕
----------client0释放----------
客户端关闭。。。。