<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
@Getter
public 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 lock
Client 10 releasing the lock
Client 38 has the lock
Client 38 releasing the lock
Client 97 has the lock
Client 97 releasing the lock
Client 76 has the lock
Client 76 releasing the lock
Client 50 has the lock
Client 50 releasing the lock
Client 34 has the lock
Client 34 releasing the lock
Client 33 has the lock
Client 33 releasing the lock
Client 2 has the lock
Client 2 releasing the lock
Client 78 has the lock
Client 78 releasing the lock
Client 18 has the lock
Client 18 releasing the lock
Client 49 has the lock
Client 49 releasing the lock
Client 82 has the lock
Client 82 releasing the lock
Client 77 has the lock
Client 77 releasing the lock
Client 51 has the lock
Client 51 releasing the lock
参考资料:http://www.jianshu.com/p/70151fc0ef5d
Curator深入使用:http://www.cnblogs.com/LiZhiW/p/4926385.html