zookeeper實現互斥鎖

簡單的說,zookeeper就是爲了解決集羣環境中數據一致性的問題。服務器

舉個很簡單栗子:多線程

有一個變量A,分別存在於兩臺服務器中,某個程序須要用到變量A,就隨機地訪問其中一臺服務器並取得變量A的值,對吧?如今有兩個客戶端分別修改兩臺服務器上的變量A,其中一個客戶端把其中一臺服務器的變量A的值修改成1,另外一個客戶端把另外一臺服務器的變量A修改成2。那麼以後,程序訪問取得這個變量的值,究竟是1仍是2呢?zookeeper就是爲了解決這種問題的。ide

本文主要是講一個demo,利用zookeeper的特性來實現一個互斥鎖,原理性的東西本文不贅述。函數

咱們用多線程的方式來模擬多個客戶端爭搶鎖,線程類代碼以下:spa

public class Thread1 implements Runnable {
        ZooKeeper zk = null;

        @Override
        public void run() {
            try {
                zk = new ZooKeeper("127.0.0.1:2181", 2000, new Watcher() {
                    @Override
                    public void process(WatchedEvent event) {
                        // 獲取事件類型
                        String type = event.getType().toString();
                        /**
                         * 咱們使用節點/lock/mylock爲鎖的標誌
                         * 事件類型爲「None」表示線程剛啓動,線程啓動後就當即去搶鎖
                         * 事件類型爲「NodeDeleted」表示有節點被刪除了
                         * ,也就表示有線程釋放鎖了,當前線程獲得事件通知後就當即搶鎖
                         * 。if塊裏面的代碼都是搶鎖、處理業務邏輯、釋放鎖這個流程
                         */
                        if ("None".equals(type) || ("NodeDeleted".equals(type) && event.getPath().equals("/lock/mylock"))) {
                            try {
                                // 建立一個/lock/mylock節點,即執行搶鎖。若是節點建立失敗,則會拋出一個異常,進入下面的catch塊中
                                zk.create("/lock/mylock", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

                                // 繼續監控/lock/mylock節點的變化狀況,由於zookeeper的watcher是一次性的,因此用完後要從新watch
                                zk.exists("/lock/mylock", true);

                                // /lock/mylock節點建立成功,表示搶到了鎖
                                System.out.println("----------------------------------");
                                System.out.println(Thread.currentThread().getName() + "搶到鎖了");
                                System.out.println(Thread.currentThread().getName() + "處理業務邏輯……");
                                Thread.sleep(2000);

                                // 刪除/lock/mylock節點,釋放鎖,以後全部的watch這個節點的線程都會收到事件通知,從而當即搶鎖
                                zk.delete("/lock/mylock", -1);
                                System.out.println(Thread.currentThread().getName() + "已釋放鎖");
                            } catch (Exception e) {
                                System.out.println(Thread.currentThread().getName() + "沒搶到鎖");
                                try {
                                    // 搶鎖失敗,繼續監控鎖標誌節點的變化狀況
                                    zk.exists("/lock/mylock", true);
                                } catch (Exception e1) {
                                    e1.printStackTrace();
                                }
                            }
                        }
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

 

main函數代碼以下:線程

for (int i = 0; i < 5; i++) {
            new Thread(new Thread1()).start();
        }
        System.in.read();

 

運行結果:code

Thread-3-EventThread搶到鎖了
Thread-3-EventThread處理業務邏輯……
Thread-2-EventThread沒搶到鎖
Thread-4-EventThread沒搶到鎖
Thread-0-EventThread沒搶到鎖
Thread-1-EventThread沒搶到鎖
Thread-3-EventThread已釋放鎖
----------------------------------
Thread-2-EventThread沒搶到鎖
Thread-0-EventThread沒搶到鎖
Thread-1-EventThread沒搶到鎖
Thread-3-EventThread沒搶到鎖
Thread-4-EventThread搶到鎖了
Thread-4-EventThread處理業務邏輯……
Thread-4-EventThread已釋放鎖
----------------------------------
Thread-3-EventThread沒搶到鎖
Thread-1-EventThread沒搶到鎖
Thread-2-EventThread沒搶到鎖
Thread-4-EventThread沒搶到鎖
Thread-0-EventThread搶到鎖了
Thread-0-EventThread處理業務邏輯……
Thread-0-EventThread已釋放鎖
----------------------------------
Thread-4-EventThread沒搶到鎖
Thread-3-EventThread沒搶到鎖
Thread-2-EventThread沒搶到鎖
Thread-0-EventThread沒搶到鎖
Thread-1-EventThread搶到鎖了
Thread-1-EventThread處理業務邏輯……
Thread-1-EventThread已釋放鎖
----------------------------------
Thread-0-EventThread沒搶到鎖
Thread-2-EventThread沒搶到鎖
Thread-4-EventThread沒搶到鎖
Thread-1-EventThread沒搶到鎖
Thread-3-EventThread搶到鎖了
Thread-3-EventThread處理業務邏輯……
Thread-3-EventThread已釋放鎖
----------------------------------
Thread-0-EventThread沒搶到鎖
Thread-4-EventThread沒搶到鎖
Thread-2-EventThread沒搶到鎖
Thread-3-EventThread沒搶到鎖
Thread-1-EventThread搶到鎖了
Thread-1-EventThread處理業務邏輯……
Thread-1-EventThread已釋放鎖
----------------------------------
Thread-3-EventThread沒搶到鎖
Thread-2-EventThread沒搶到鎖
Thread-4-EventThread沒搶到鎖
Thread-1-EventThread沒搶到鎖
Thread-0-EventThread搶到鎖了
Thread-0-EventThread處理業務邏輯……
Thread-0-EventThread已釋放鎖
----------------------------------
Thread-2-EventThread沒搶到鎖
Thread-0-EventThread沒搶到鎖
Thread-4-EventThread沒搶到鎖
Thread-1-EventThread沒搶到鎖
Thread-3-EventThread搶到鎖了
Thread-3-EventThread處理業務邏輯……
Thread-3-EventThread已釋放鎖
----------------------------------
Thread-0-EventThread沒搶到鎖
Thread-2-EventThread沒搶到鎖
Thread-3-EventThread沒搶到鎖
Thread-1-EventThread搶到鎖了
Thread-1-EventThread處理業務邏輯……
Thread-4-EventThread沒搶到鎖

咱們能夠看到每次只有一個線程獲取到了鎖,並處理業務邏輯blog

相關文章
相關標籤/搜索