There is no such thing as a perfect program, but we don’t get discouraged because writing programs is a constant pursuit of perfection.

The principle of distributed lock is actually very simple, of course, fundamentally speaking, the implementation principle of all locks is the same, no matter how complex the lock, the bottom is CAS. A Distributed lock of ZooKeeper is implemented in accordance with CAS principles.

public class ZKTest {

    public static void main(String[] args) {
        for (int i=0; i<8; i++) {
            newThread(ZKTest::run).start(); }}private static void run(a) {
        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(a) {
        return Long.toString(new Random().nextLong());
    }

    private static ZooKeeper zk(a) {
        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; }}}Copy the code

Output result:

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.Copy the code

Because ZooKeeper is globally consistent, so, this program whether on a single server, or in the cluster effect is consistent, can ensure thread safety.