1、多线程的模拟实现:
package DistributedLock;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
/**
* 分布式共享锁的简单实现
* Created by tianjun on 2016/12/19 0019.
*/
public class DistributedClient {
private static final int SESSION_TIMEOUT=5000;
private String hosts = "mini04:2181,mini05:2181,mini06:2181";
private String groupNode = "locks";
private String subNode = "sub";
private ZooKeeper zk = null;
private String thisPath = null;
private String waitPath = null;
private CountDownLatch latch = new CountDownLatch(1);
public void connnectZookeeper() throws IOException, KeeperException, InterruptedException {
zk = new ZooKeeper(hosts, SESSION_TIMEOUT, new Watcher() {
public void process(WatchedEvent event) {
if(event.getState() == Event.KeeperState.SyncConnected){
latch.countDown();
}
if(event.getType() == Event.EventType.NodeDeleted && event.getPath().equals(waitPath)){
try {
doSomething();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
}
}
}
});
latch.await();
thisPath = zk.create("/"+groupNode+"/"+subNode,null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
Thread.sleep(10);
List<String> childrenNodes = zk.getChildren("/"+groupNode,false);
if(childrenNodes.size() == 1){
doSomething();
}else{
String thisNode = thisPath.substring(("/"+groupNode+"/").length());
Collections.sort(childrenNodes);
int index = childrenNodes.indexOf(thisNode);
if(index==-1){
}else if(index == 0){
doSomething();
}else{
this.waitPath = "/"+groupNode+"/"+childrenNodes.get(index - 1);
zk.getData(waitPath,true,new Stat());
}
}
}
private void doSomething() throws InterruptedException, KeeperException {
try {
System.out.println("gain lock:"+thisPath);
Thread.sleep(2000);
} finally {
System.out.println("finished:"+this.thisPath);
zk.delete(this.thisPath,-1);
}
}
public static void main(String[] args) throws InterruptedException {
for(int i =0 ; i < 10 ; i++){
new Thread(){
public void run(){
try {
DistributedClient d1 = new DistributedClient();
d1.connnectZookeeper();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
Thread.sleep(Long.MAX_VALUE);
}
}
2、分布式多进程模式实现
package DistributedLock;
import org.apache.zookeeper.*;
import java.util.Collections;
import java.util.List;
import java.util.Random;
/**
* 分布式共享锁的简单实现(多进程模式实现)
* Created by tianjun on 2016/12/19 0019.
*/
public class DistributedClientMy {
private static final int SESSION_TIMEOUT=5000;
private String hosts = "mini04:2181,mini05:2181,mini06:2181";
private String groupNode = "locks";
private String subNode = "sub";
private boolean haveLock = false;
private ZooKeeper zk = null;
private volatile String thisPath;
/**
* 连接zookeeper
*/
public void connectZookeeper() throws Exception {
zk = new ZooKeeper(hosts, SESSION_TIMEOUT, new Watcher() {
public void process(WatchedEvent event) {
try {
if (event.getType() == Event.EventType.NodeChildrenChanged && event.getPath().equals("/" + groupNode)) {
List<String> childrenNodes = zk.getChildren("/" + groupNode, true);
String thisNode = thisPath.substring(("/" + groupNode + "/").length());
Collections.sort(childrenNodes);
if (childrenNodes.indexOf(thisNode) == 0) {
doSomething();
thisPath = zk.create("/" + groupNode + "/" + subNode, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
});
thisPath = zk.create("/" + groupNode + "/" + subNode, null, ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL_SEQUENTIAL);
Thread.sleep(new Random().nextInt(1000));
List<String> childrenNodes = zk.getChildren("/" + groupNode, true);
if (childrenNodes.size() == 1) {
doSomething();
thisPath = zk.create("/" + groupNode + "/" + subNode, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
}
}
/**
* 共享资源的访问逻辑写在这个方法中
*/
private void doSomething() throws Exception {
try {
System.out.println("gain lock: " + thisPath);
Thread.sleep(2000);
} finally {
System.out.println("finished: " + thisPath);
zk.delete(this.thisPath, -1);
}
}
public static void main(String[] args) throws Exception {
DistributedClientMy dl = new DistributedClientMy();
dl.connectZookeeper();
Thread.sleep(Long.MAX_VALUE);
}
}