zk - zookeeper實現分散式鎖程式碼
阿新 • • 發佈:2021-01-05
世界上並沒有完美的程式,但是我們並不因此而沮喪,因為寫程式不斷追求完美的過程。
分散式鎖的原理其實很簡單,當然從根本上說所有鎖的實現原理其實是一致的,無論多麼複雜的鎖,底層都是CAS。這裡遵循CAS的原則實現了一個zookeeper的分散式鎖。
public class ZKTest {
public static void main(String[] args) {
for (int i=0; i<8; i++) {
new Thread(ZKTest::run).start();
}
}
private static void run() {
String serviceId = serviceId();
ZooKeeper zk = zk();
boolean lock = getLock(zk, serviceId);
if (lock) {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getId() + " " + i) ;
}
}
close(zk);
}
private static void close(ZooKeeper zk) {
try {zk.close();} catch (Exception e) {e.printStackTrace();}
}
private static boolean getLock(ZooKeeper zk, String serviceId) {
while (!isLeader(zk, serviceId)) {
toBeLeader (zk, serviceId);
}
return true;
}
private static String serviceId() {
return Long.toString(new Random().nextLong());
}
private static ZooKeeper zk() {
try {
ZooKeeper zk = new ZooKeeper("127.0.0.1:2181", 15000, new Watcher() {
@Override
public void process(WatchedEvent event) {
if (!Event.EventType.None.equals(event.getType())) {
System.out.println("watchEvent : " + event);
}
}
});
return zk;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static final String MASTER = "/master";
private static boolean isLeader(ZooKeeper zk, String serviceId) {
try {
byte[] data = zk.getData(MASTER, true, new Stat());
if (null != data && new String(data).equals(serviceId)) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
private static boolean toBeLeader(ZooKeeper zk, String serviceId) {
try {
String path = zk.create(MASTER, serviceId.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("path : " + path);
if (MASTER.equals(path)) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
}
輸出結果:
threadId : 18 no : 0
threadId : 18 no : 1
threadId : 18 no : 2
threadId : 18 no : 3
threadId : 18 no : 4
threadId : 18 no : 5
threadId : 18 no : 6
threadId : 18 no : 7
threadId : 18 no : 8
threadId : 18 no : 9
threadId : 18 no : 10
threadId : 18 no : 11
threadId : 18 no : 12
threadId : 18 no : 13
threadId : 18 no : 14
threadId : 18 no : 15
threadId : 18 no : 16
threadId : 18 no : 17
threadId : 18 no : 18
threadId : 18 no : 19
threadId : 18 no : 20
threadId : 18 no : 21
threadId : 18 no : 22
threadId : 18 no : 23
threadId : 18 no : 24
threadId : 18 no : 25
threadId : 18 no : 26
threadId : 18 no : 27
threadId : 18 no : 28
threadId : 18 no : 29
threadId : 18 no : 30
threadId : 18 no : 31
threadId : 18 no : 32
threadId : 18 no : 33
threadId : 18 no : 34
threadId : 18 no : 35
threadId : 18 no : 36
threadId : 18 no : 37
threadId : 18 no : 38
threadId : 18 no : 39
threadId : 18 no : 40
threadId : 18 no : 41
threadId : 18 no : 42
threadId : 18 no : 43
threadId : 18 no : 44
threadId : 18 no : 45
threadId : 18 no : 46
threadId : 18 no : 47
threadId : 18 no : 48
threadId : 18 no : 49
threadId : 18 no : 50
threadId : 18 no : 51
threadId : 18 no : 52
threadId : 18 no : 53
threadId : 18 no : 54
threadId : 18 no : 55
threadId : 18 no : 56
threadId : 18 no : 57
threadId : 18 no : 58
threadId : 18 no : 59
threadId : 18 no : 60
threadId : 18 no : 61
threadId : 18 no : 62
threadId : 18 no : 63
threadId : 18 no : 64
threadId : 18 no : 65
threadId : 18 no : 66
threadId : 18 no : 67
threadId : 18 no : 68
threadId : 18 no : 69
threadId : 18 no : 70
threadId : 18 no : 71
threadId : 18 no : 72
threadId : 18 no : 73
threadId : 18 no : 74
threadId : 18 no : 75
threadId : 18 no : 76
threadId : 18 no : 77
threadId : 18 no : 78
threadId : 18 no : 79
threadId : 18 no : 80
threadId : 18 no : 81
threadId : 18 no : 82
threadId : 18 no : 83
threadId : 18 no : 84
threadId : 18 no : 85
threadId : 18 no : 86
threadId : 18 no : 87
threadId : 18 no : 88
threadId : 18 no : 89
threadId : 18 no : 90
threadId : 18 no : 91
threadId : 18 no : 92
threadId : 18 no : 93
threadId : 18 no : 94
threadId : 18 no : 95
threadId : 18 no : 96
threadId : 18 no : 97
threadId : 18 no : 98
threadId : 18 no : 99
threadId : 21 no : 0
threadId : 21 no : 1
threadId : 21 no : 2
threadId : 21 no : 3
threadId : 21 no : 4
threadId : 21 no : 5
threadId : 21 no : 6
threadId : 21 no : 7
threadId : 21 no : 8
threadId : 21 no : 9
threadId : 21 no : 10
threadId : 21 no : 11
threadId : 21 no : 12
threadId : 21 no : 13
threadId : 21 no : 14
threadId : 21 no : 15
threadId : 21 no : 16
threadId : 21 no : 17
threadId : 21 no : 18
threadId : 21 no : 19
threadId : 21 no : 20
threadId : 21 no : 21
threadId : 21 no : 22
threadId : 21 no : 23
threadId : 21 no : 24
threadId : 21 no : 25
threadId : 21 no : 26
threadId : 21 no : 27
threadId : 21 no : 28
threadId : 21 no : 29
threadId : 21 no : 30
threadId : 21 no : 31
threadId : 21 no : 32
threadId : 21 no : 33
threadId : 21 no : 34
threadId : 21 no : 35
threadId : 21 no : 36
threadId : 21 no : 37
threadId : 21 no : 38
threadId : 21 no : 39
threadId : 21 no : 40
threadId : 21 no : 41
threadId : 21 no : 42
threadId : 21 no : 43
threadId : 21 no : 44
threadId : 21 no : 45
threadId : 21 no : 46
threadId : 21 no : 47
threadId : 21 no : 48
threadId : 21 no : 49
threadId : 21 no : 50
threadId : 21 no : 51
threadId : 21 no : 52
threadId : 21 no : 53
threadId : 21 no : 54
threadId : 21 no : 55
threadId : 21 no : 56
threadId : 21 no : 57
threadId : 21 no : 58
threadId : 21 no : 59
threadId : 21 no : 60
threadId : 21 no : 61
threadId : 21 no : 62
threadId : 21 no : 63
threadId : 21 no : 64
threadId : 21 no : 65
threadId : 21 no : 66
threadId : 21 no : 67
threadId : 21 no : 68
threadId : 21 no : 69
threadId : 21 no : 70
threadId : 21 no : 71
threadId : 21 no : 72
threadId : 21 no : 73
threadId : 21 no : 74
threadId : 21 no : 75
threadId : 21 no : 76
threadId : 21 no : 77
threadId : 21 no : 78
threadId : 21 no : 79
threadId : 21 no : 80
threadId : 21 no : 81
threadId : 21 no : 82
threadId : 21 no : 83
threadId : 21 no : 84
threadId : 21 no : 85
threadId : 21 no : 86
threadId : 21 no : 87
threadId : 21 no : 88
threadId : 21 no : 89
threadId : 21 no : 90
threadId : 21 no : 91
threadId : 21 no : 92
threadId : 21 no : 93
threadId : 21 no : 94
threadId : 21 no : 95
threadId : 21 no : 96
threadId : 21 no : 97
threadId : 21 no : 98
threadId : 21 no : 99
....................
由於zookeeper是全域性一致的,所以,本程式無論是在單個伺服器上,還是在叢集中效果是一致的,都可以保證執行緒安全。