Zookeeper distributed lock

The following briefly introduces the application and principle of using Curator to implement zk distributed lock.

1. Connect the Factory class of zk

 

package com.zk;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;

public class ZkClientFactory {
	 private static CuratorFramework client;
	 //Construct the global zk link object
	 public static CuratorFramework  getInstance(String url){
		 if(null == client){
			 synchronized(ZkClientFactory.class){
				 if(null == client){
					 CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder();  
				        client = builder.connectString(url)
				        		.sessionTimeoutMs(3000)  
				                .connectionTimeoutMs(3000)  
				                .canBeReadOnly(false)  
				                .retryPolicy(new ExponentialBackoffRetry(1000, Integer.MAX_VALUE))  
				                .namespace(null)  
				                .defaultData(null)  
				                .build();  
				        client.start();
				 }
			 }
		 }
		 return client;
	 }
}

2. Simulate multiple threads to compete for locks

 

 

class MyJob extends Thread{
	CuratorFramework client;
	
	public MyJob(CuratorFramework client){
		this.client = client;
	}
	public void run(){
		InterProcessMutex lock = new InterProcessMutex(client, "/test");
    	try {
			//lock.acquire();//It will block until the lock is acquired successfully
    		boolean locked= lock.acquire(2000, TimeUnit.MILLISECONDS);//Get the lock successfully or block for a certain time and return
    		if(locked){
    			System.out.println(this.getName()+"Successful lock acquisition");
    			Thread.sleep(3000);
    		}else{
    			System.out.println(this.getName()+"Failed to acquire lock");
    		}
		} catch (Exception e) {
	
		}finally{
			try {
				lock.release();
				System.out.println(this.getName()+"release lock successful");
			} catch (Exception e) {
				
			}
		}
	}
}

 3. Test

public class Lock {
  	private static final String ZK_ADDRESS = "127.0.0.1:2182";
  	
    private static CuratorFramework client = ZkClientFactory.getInstance(ZK_ADDRESS);
    
    public static void main(String[] args){
    	MyJob jb1 = new MyJob (client);
    	MyJob jb2 = new MyJob (client);
    	MyJob jb3 = new MyJob (client);
    	jb1.start();
    	jb2.start();
    	jb3.start();
    }

}

 4. Print the result:

 

Thread-2 acquires the lock successfully

Thread-1 failed to acquire lock

Thread-3 failed to acquire lock

Thread-2 released the lock successfully

 

 5. If the locked code is replaced:

Bundle

boolean locked= lock.acquire(2000, TimeUnit.MILLISECONDS);//Get the lock successfully or block for a certain time and return
 if(locked){
    	System.out.println(this.getName()+"Successful lock acquisition");
    	Thread.sleep(3000);
 }else{
    	System.out.println(this.getName()+"Failed to acquire lock");
 }

 Replace with:

lock.acquire();//It will block until the lock is acquired successfully
System.out.println(this.getName()+"Successful lock acquisition");
Thread.sleep(3000);

 The print result is as follows:

Thread-3 acquires the lock successfully

Thread-3 released the lock successfully

Thread-2 acquires the lock successfully

Thread-2 released the lock successfully

Thread-1 acquires the lock successfully

Thread-1 released the lock successfully

It can be seen that all three threads can acquire the lock sequentially. So which method to use depends on your usage scenario.

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326423001&siteId=291194637