本地使用Zookeeper偽集群模式钉跷,同步鎖控制多個進(jìn)程的同步狀態(tài)。
1彬坏、獲取鎖
實現(xiàn)方式:
1.各個進(jìn)程創(chuàng)建一個EPHEMERAL_SEQUENTIAL目錄節(jié)點。
2.調(diào)用getChildren方法獲取當(dāng)前的目錄節(jié)點列表中最小的目錄節(jié)點栓始,
如果是自己創(chuàng)建的血当,那么它就獲得了這個鎖;
如果不是自己創(chuàng)建的調(diào)用exists()臊旭;并監(jiān)控 Zookeeper 上目錄節(jié)點列表的變化,
一直到自己創(chuàng)建的節(jié)點是列表中最小編號的目錄節(jié)點就可以獲得鎖离熏。
2、釋放鎖
實現(xiàn)方式:
1.獲取到鎖的Server刪除自己所創(chuàng)建的目錄節(jié)點钻蔑。
3奸鸯、代碼示例
public class MainTest implements Runnable {
private static ZooKeeper zooKeeper;
private static String root = "/xmy";
private static String tempZnode = "/lock";
private static String myZnode = null;
private static String hostPort = "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183";
public static void main(String[] args) throws Exception {
zooKeeper = new ZooKeeper(hostPort, 5000, null);
//創(chuàng)建一個EPHEMERAL_SEQUENTIAL目錄節(jié)點
myZnode = zooKeeper.create(root + tempZnode, "value".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println("----------創(chuàng)建的目錄名為:" + myZnode);
MainTest mainTest = new MainTest();
mainTest.tryLock();
}
/**
* 獲取鎖
*/
public void tryLock() throws Exception {
System.out.println("----------搶鎖開始----------");
List<String> list = zooKeeper.getChildren(root, false);
String[] nodes = list.toArray(new String[list.size()]);
Arrays.sort(nodes);
if (myZnode.equals(root + "/" + nodes[0])) {
System.out.println("----------我搶到了鎖----------");
Thread.sleep(60 * 1000);
System.out.println("----------執(zhí)行1分鐘任務(wù)結(jié)束----------");
doReleaseShared();
} else {
waitForLock(nodes[0]);
}
}
void waitForLock(String lower) throws Exception {
System.out.println("----------未獲取到鎖----------");
//監(jiān)聽
Watcher childrenWatcher = new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println("----------收到的消息: " + event.toString());
if (event.getType() == Event.EventType.NodeDeleted) {
try {
synchronized (this) {
notifyAll();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
};
}
/**
* 釋放鎖
*/
public void doReleaseShared() throws Exception {
System.out.println("----------我釋放了鎖----------");
zooKeeper.delete(myZnode, -1);
}
@Override
public void run() {
try {
synchronized (this) {
while (true) {
wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
} finally {
this.close();
}
}
public synchronized void close() {
try {
zooKeeper.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}