1. The first way to realize , Multiple threads to zk Create a temporary node next , If a thread creates a node successfully , It means the lock is obtained , If the creation fails , It will enter the waiting state , Monitor temporary nodes , Until the lock is released , The temporary node disappears , Perform the lock acquisition operation again . There will be a problem in this way , In the case of large concurrency , The disappearance of a temporary node , Many threads will try to create temporary nodes at the same time , This will affect zk Stability of , This effect is called herding .
package com.tech.demo.zookeeper; import org.apache.zookeeper.*; import
org.apache.zookeeper.data.Stat; import java.io.IOException; import
java.util.concurrent.*; import java.util.concurrent.locks.Condition; import
java.util.concurrent.locks.Lock; /** * @author xxx_xx * @date 2018/8/13 */
public class DistedLock extends Thread implements Lock, Watcher { private
ZooKeeper zk; private String root = "/lock"; private String childPath =
"/lock/child"; private CountDownLatch latch = new CountDownLatch(1); /** *
Initialize if there is no root node , Create root node */ public DistedLock(String threadName) { super(threadName);
try { this.zk = new ZooKeeper("localhost:2181", 2000, this); Stat stat =
zk.exists(root, true); if (stat == null) { zk.create(root, "root".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } } catch (IOException e)
{ e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace();
} catch (KeeperException e) { e.printStackTrace(); } } @Override public void
lock() { if (tryLock()) { System.out.println(Thread.currentThread().getName() +
" Get lock "); } else { waitLock(); } } public void waitLock() { try { // Register to listen
zk.exists(childPath, true); // wait for latch.await();
System.out.println(Thread.currentThread().getName() + " Thread grabs lock again "); lock();
Thread.sleep(1000); } catch (KeeperException e) { e.printStackTrace(); } catch
(InterruptedException e) { e.printStackTrace(); } } @Override public void
lockInterruptibly() throws InterruptedException { } @Override public boolean
tryLock() { try { Stat stat = zk.exists(childPath, true); if (stat != null) {
return false; } else { String val = zk.create(childPath, "child1".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println(Thread.currentThread().getName() + val + " Node creation "); } return
true; } catch (KeeperException e) { e.printStackTrace(); } catch
(InterruptedException e) { e.printStackTrace(); } return false; } @Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false; } @Override public void unlock() { try { zk.delete(childPath,
-1); } catch (InterruptedException e) { e.printStackTrace(); } catch
(KeeperException e) { e.printStackTrace(); } } @Override public Condition
newCondition() { return null; } @Override public void process(WatchedEvent
watchedEvent) { if (watchedEvent != null) { this.latch.countDown(); } } public
static void main(String[] args) { new DistedLock(" thread ").start(); new
DistedLock(" thread 1").start(); new DistedLock(" thread 2").start(); new
DistedLock(" thread 3").start(); } @Override public void run() { this.lock(); try {
Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
this.unlock(); } }
2. The second way to realize , Each thread in zk Next create a temporary sequence node , If the current node is the smallest of the temporary sequence nodes, it means that it gets the lock , If not

Just listen to a node smaller than yourself , Examples , If all three threads create three temporary sequence nodes , The serial numbers are 0,1,2, thread 1 Find your own node is the smallest , You think you've got the lock , return true Created successfully , thread 2 And threads 3 Find that your own node is not the smallest , So threads 2 Monitor serial number is 0 Node of , thread 3 Monitor serial number is 1 Node of , In this way, each thread can only listen to one node .
package com.tech.demo.zookeeper; import org.apache.zookeeper.*; import
org.apache.zookeeper.data.Stat; import java.io.IOException; import
java.util.ArrayList; import java.util.Collections; import java.util.List;
import java.util.concurrent.CountDownLatch; import
java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock; /** * @author xxx_xx * @date 2018/8/19
*/ public class TestLock implements Lock, Watcher { private ZooKeeper zk =
null; private String ROOT_LOCK = "/lo"; private String lockName; private String
WAIT_LOCK; private String CURRENT_LOCK; private CountDownLatch countDownLatch;
private int sessionTimeout = 30000; private List<Exception> exceptionList = new
ArrayList<Exception>(); /** * Configure distributed locks * * @param config Connected url * @param lockName
Competitive resources */ public TestLock(String config, String lockName) { this.lockName =
lockName; try { // connect zookeeper zk = new ZooKeeper(config, sessionTimeout,
this); Stat stat = zk.exists(ROOT_LOCK, false); if (stat == null) { //
If the root node does not exist , Then create the root node zk.create(ROOT_LOCK, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT); } } catch (IOException e) { e.printStackTrace(); }
catch (InterruptedException e) { e.printStackTrace(); } catch (KeeperException
e) { e.printStackTrace(); } } // Node monitor public void process(WatchedEvent event)
{ if (this.countDownLatch != null) { this.countDownLatch.countDown(); } }
public void lock() { if (exceptionList.size() > 0) { throw new
LockException(exceptionList.get(0)); } try { if (this.tryLock()) {
System.out.println(Thread.currentThread().getName() + " " + lockName + " Lock obtained ");
return; } else { // Wait for lock waitForLock(WAIT_LOCK, sessionTimeout); } } catch
(InterruptedException e) { e.printStackTrace(); } catch (KeeperException e) {
e.printStackTrace(); } } public boolean tryLock() { try { String splitStr =
"_lock_"; if (lockName.contains(splitStr)) { throw new LockException(" Wrong lock name "); }
// Create a temporary ordered node CURRENT_LOCK = zk.create(ROOT_LOCK + "/" + lockName + splitStr, new
byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(CURRENT_LOCK + " Created "); // Take all child nodes List<String> subNodes =
zk.getChildren(ROOT_LOCK, false); // Remove all lockName Lock of List<String> lockObjects =
new ArrayList<String>(); for (String node : subNodes) { String _node =
node.split(splitStr)[0]; if (_node.equals(lockName)) { lockObjects.add(node); }
} Collections.sort(lockObjects);
System.out.println(Thread.currentThread().getName() + " The lock is " + CURRENT_LOCK);
// If the current node is the minimum node , Get the lock successfully if (CURRENT_LOCK.equals(ROOT_LOCK + "/" +
lockObjects.get(0))) { return true; } // If not the minimum node , Then find your previous node String prevNode =
CURRENT_LOCK.substring(CURRENT_LOCK.lastIndexOf("/") + 1); WAIT_LOCK =
lockObjects.get(Collections.binarySearch(lockObjects, prevNode) - 1); } catch
(InterruptedException e) { e.printStackTrace(); } catch (KeeperException e) {
e.printStackTrace(); } return false; } public boolean tryLock(long timeout,
TimeUnit unit) { try { if (this.tryLock()) { return true; } return
waitForLock(WAIT_LOCK, timeout); } catch (Exception e) { e.printStackTrace(); }
return false; } // Wait for lock private boolean waitForLock(String prev, long waitTime)
throws KeeperException, InterruptedException { // Monitor nodes smaller than yourself Stat stat =
zk.exists(ROOT_LOCK + "/" + prev, true); if (stat != null) {
System.out.println(Thread.currentThread().getName() + " Wait for lock " + ROOT_LOCK + "/"
+ prev); this.countDownLatch = new CountDownLatch(1); //
Count wait , If you wait until the previous node disappears , be precess In progress countDown, Stop waiting , Acquire lock
this.countDownLatch.await(waitTime, TimeUnit.MILLISECONDS); this.countDownLatch
= null; System.out.println(Thread.currentThread().getName() + " Wait for the lock "); }
return true; } public void unlock() { try { System.out.println(" Release lock " +
CURRENT_LOCK); zk.delete(CURRENT_LOCK, -1); CURRENT_LOCK = null; zk.close(); }
catch (InterruptedException e) { e.printStackTrace(); } catch (KeeperException
e) { e.printStackTrace(); } } public Condition newCondition() { return null; }
public void lockInterruptibly() throws InterruptedException { this.lock(); }
public class LockException extends RuntimeException { private static final long
serialVersionUID = 1L; public LockException(String e) { super(e); } public
LockException(Exception e) { super(e); } } }
 

Test code
package com.tech.demo.zookeeper; /** * @author xxx_xx * @date 2018/8/19 */
public class Test { static int n = 500; public static void main(String[] args)
{ Runnable runnable = new Runnable() { public void run() { TestLock lock =
null; try { lock = new TestLock("localhost:2181", "test1"); lock.lock();
System.out.println(Thread.currentThread().getName() + " Running "); } finally { if
(lock != null) { lock.unlock(); } } } }; for (int i = 0; i < 3; i++) { Thread t
= new Thread(runnable); t.start(); } } }
 

 

 

 

 

 

 

Technology
©2019-2020 Toolsou All rights reserved,
JS How to operate java Realize the function of grabbing red packets C Language programming to find a student's grade The United Nations 《 Glory of Kings 》 Please go to the studio : To save the earth Dialogue between apple and Nissan suspended ,Apple Car How's it going ?CSS architecture design China's longest high speed rail officially opened ! The fastest way to finish the race 30.5 hour First knowledge MySQL Comprehensive review ( dried food )2021 year 1 Monthly programmer salary statistics , average 14915 element How to use it quickly html and css Write static page