Implementation of a simple distributed lock based on zookeeper

Source: Internet
Author: User
Tags sleep zookeeper root directory

Zookeeper is a distributed, open-source distributed Application coordination Service. Based on zookeeper, we can implement a simple distributed mutex, which includes reentrant and non-reentrant. The code is as follows:

Import java.io.IOException;
Import java.util.ArrayList;

Import Java.util.Random;
Import Org.apache.zookeeper.CreateMode;
Import org.apache.zookeeper.KeeperException;
Import org.apache.zookeeper.WatchedEvent;
Import Org.apache.zookeeper.Watcher;
Import Org.apache.zookeeper.ZooDefs.Ids;

Import Org.apache.zookeeper.ZooKeeper;

	public class Testzookeeperdistributelock {//Is reentrant lock private Boolean reentrant = false;
	public Boolean isreentrant () {return reentrant;

	} private ZooKeeper ZK = null;
	Public ZooKeeper Getzk () {return ZK;

		} public Testzookeeperdistributelock (Boolean reentrant) {this.reentrant = reentrant;
	Initialize the environment: connect the Zookeeper and create the root directory init ();
			} private void Init () {try {System.out.println ("...");
			System.out.println ("...");
			System.out.println ("...");

			System.out.println ("...");

			System.out.println ("Start connecting zookeeper ...");
			Create a connection to the Zookeeper server ZK String address = "192.168.1.226:2181";
			int sessiontimeout = 3000; ZK = new ZooKeeper(Address, Sessiontimeout, new Watcher () {//monitor all triggered events public void process (Watchedevent event) {if (event.g Ettype () = = NULL | |
					". Equals (Event.gettype ())) {return; } System.out.println ("The" + event.gettype () + "event has been triggered.)
				");

			}
			}); System.out.println ("The zookeeper connection was created successfully.

			");

			Thread.CurrentThread (). Sleep (1000l);
			System.out.println ("...");
			System.out.println ("...");
			System.out.println ("...");

			System.out.println ("..."); Create root directory Node//path to/tmp_root_path//node content as String "I am root directory/tmp_root_path"//Create mode is Createmode.persistent System.out.prin
			TLN ("Start creating root node/tmp_root_path ...");
			Zk.create ("/tmp_root_path", "I am the root directory/tmp_root_path". GetBytes (), Ids.open_acl_unsafe, createmode.persistent); SYSTEM.OUT.PRINTLN ("Root directory node/tmp_root_path created successfully.

			");

			Thread.CurrentThread (). Sleep (1000l);
			System.out.println ("...");
			System.out.println ("...");
			System.out.println ("...");
		System.out.println ("..."); } catch (Exception e) {ZK = null;
		}} public void Destroy () {//delete root node try {System.out.println ("Start removing root node/tmp_root_path ...");
			Zk.delete ("/tmp_root_path",-1); SYSTEM.OUT.PRINTLN ("Root directory node/tmp_root_path deleted successfully.
		");
		} catch (Interruptedexception E1) {//TODO auto-generated catch block E1.printstacktrace ();
		} catch (Keeperexception E1) {//TODO auto-generated catch block E1.printstacktrace ();
				}//Close connection if (ZK! = null) {try {zk.close (); System.out.println ("Release zookeeper connection succeeded.

			");
			} catch (Interruptedexception e) {//TODO auto-generated catch block E.printstacktrace ();  }}} public static void Main (string[] args) {final Testzookeeperdistributelock testzookeeperdistributelock = new
		Testzookeeperdistributelock (TRUE);

		Final random radom = new Random ();
		try {thread.currentthread (). Sleep (1000l);
		} catch (interruptedexception E2) {//TODO auto-generated catch block E2.printstacktrace (); } arraylist<thread> threadlist = nEW arraylist<thread> ();  for (int i = 0; i < 4; i++) {Thread thread = new Thread () {@Override public void Run () {Boolean
					Locked = FALSE; while (true) {try {//Create the directory node that needs to acquire the lock, the success of the creation indicates the ability to acquire the lock and the creation is unsuccessful, then the lock has been acquired by another thread (even for a different process)/path is/tmp_root_path/l Ock//node content is the current thread name//creation mode is createmode.persistent System.out.println ("thread" + Thread.currentthre
							AD (). GetName () + "try to get lock ...");
													Testzookeeperdistributelock.getzk (). Create ("/tmp_root_path/lock", Thread.CurrentThread (). GetName ()
							. GetBytes (), Ids.open_acl_unsafe, createmode.persistent); SYSTEM.OUT.PRINTLN ("Thread" + thread.currentthread (). GetName () + "successfully acquired the lock.

							");

							Locked = true;
							SYSTEM.OUT.PRINTLN ("Thread" + thread.currentthread (). GetName () + "Start processing business logic ...");
							Thread.CurrentThread (). Sleep (+ radom.nextint (3000)); System.out.pRINTLN ("Thread" + thread.currentthread (). GetName () + "business logic is finished.

						"); } catch (Exception e) {if (Testzookeeperdistributelock.isreentrant ()) {try {String Lockthread = new String (testzookeeperdistributelock. Getzk (). GetData ("/tmp_roo
									T_path/lock ", false, null)); if (lockthread! = null) {////When the thread is in the same name as the lock that was acquired, the lock if (lockthread.equals (thread. Currentthr) is re-entered.
													EAD (). GetName ()) {System.out.println ("thread" + thread.currentthread (). GetName () + "Successfully re-enter the lock.

											");

											Locked = true;
											SYSTEM.OUT.PRINTLN ("Thread" + thread.currentthread (). GetName () + "Start processing business logic ...");
											Thread.CurrentThread (). Sleep (+ radom.nextint (3000));
								SYSTEM.OUT.PRINTLN ("Thread" + thread.currentthread (). GetName ()					+ "The business logic is processed.
										");  } else {System.out.println ("thread" + thread.currentthread (). GetName () + "An attempt to acquire a lock failed, and the lock was consumed by thread" + Lockthread + ".
										"); }}} catch (Keeperexception E1) {//TODO auto-generated catch block E1.printstacktra
								CE ();
								} catch (Interruptedexception E1) {//TODO auto-generated catch block E1.printstacktrace (); }} else {System.out.println ("thread" + thread.currentthread (). GetName () + "attempt to acquire lock failed.
							");
							try {thread.currentthread (). Sleep (+ + radom.nextint (3000));
							} catch (Interruptedexception E1) {//TODO auto-generated catch block E1.printstacktrace (); }} finally {try {if (locked) {System.out.println ("thread" + thread.currentthread
									(). GetName () + "Start release lock ..."); TestzookeeperdisTributelock.getzk (). Delete ("/tmp_root_path/lock",-1); SYSTEM.OUT.PRINTLN ("Thread" + thread.currentthread (). GetName () + "release lock successfully.

									");
								Thread.CurrentThread (). Sleep (+ radom.nextint (3000));
							}} catch (Interruptedexception e) {//TODO auto-generated catch block E.printstacktrace ();
							} catch (Keeperexception e) {//TODO auto-generated catch block E.printstacktrace ();
							} finally {locked = false;
			
			}
						}
					}

				}
			};
			
			Threadlist.add (thread);
		Thread.Start ();
		try {thread.currentthread (). Sleep (1000 * 20);
		} catch (Interruptedexception e) {//TODO auto-generated catch block E.printstacktrace ();
			} for (int i = 0; i < threadlist.size (); i++) {Thread thread = threadlist.get (i);
		Thread.stop ();

	}//Release resources Testzookeeperdistributelock.destroy (); }
}
The results of the operation are as follows:

...
...
...
...
Start Connecting zookeeper ...
Zookeeper connection creation succeeded.
The None event has been triggered.
...
...
...
...
Start creating root directory Node/tmp_root_path ...
Root node/tmp_root_path was created successfully.
...
...
...
...
Thread Thread-0 trying to get lock ...
Thread Thread-2 trying to get lock ...
Thread Thread-3 trying to get lock ...
Thread Thread-1 trying to get lock ...
Thread Thread-0 successfully acquires the lock.
Thread Thread-0 begins processing business logic ...
Thread Thread-1 attempt to acquire a lock failed, and the lock is occupied by thread Thread-0.
Thread Thread-2 attempt to acquire a lock failed, and the lock is occupied by thread Thread-0.
Thread Thread-3 attempt to acquire a lock failed, and the lock is occupied by thread Thread-0.
Thread Thread-1 trying to get lock ...
Thread Thread-1 attempt to acquire a lock failed, and the lock is occupied by thread Thread-0.
Thread Thread-2 trying to get lock ...
Thread Thread-2 attempt to acquire a lock failed, and the lock is occupied by thread Thread-0.
Thread Thread-3 trying to get lock ...
Thread Thread-3 attempt to acquire a lock failed, and the lock is occupied by thread Thread-0.
Thread Thread-0 The business logic has finished processing.
Thread Thread-0 Start release lock ...
Thread Thread-0 successfully released the lock.
Thread Thread-2 trying to get lock ...
Thread Thread-2 successfully acquires the lock.
Thread Thread-2 begins processing business logic ...
Thread Thread-1 trying to get lock ...
Thread Thread-1 attempt to acquire a lock failed, and the lock is occupied by thread Thread-2.
Thread Thread-3 trying to get lock ...
Thread Thread-3 attempt to acquire a lock failed, and the lock is occupied by thread Thread-2.
Thread Thread-0 trying to get lock ...
Thread Thread-0 attempt to acquire a lock failed, and the lock is occupied by thread Thread-2.
Thread Thread-2 The business logic has finished processing.
Thread Thread-2 Start release lock ...
Thread Thread-2 successfully released the lock.
Thread Thread-3 trying to get lock ...
Thread Thread-1 trying to get lock ...
Thread Thread-3 successfully acquires the lock.
Thread Thread-3 begins processing business logic ...
Thread Thread-1 attempt to acquire a lock failed, and the lock is occupied by thread Thread-3.
Thread Thread-0 trying to get lock ... Thread Thread-0 trying to get the lockFailed, the lock is Thread-3 by the thread.
Thread Thread-2 trying to get lock ...
Thread Thread-2 attempt to acquire a lock failed, and the lock is occupied by thread Thread-3.
Thread Thread-3 The business logic has finished processing.
Thread Thread-3 Start release lock ...
Thread Thread-3 successfully released the lock.
Thread Thread-0 trying to get lock ...
Thread Thread-0 successfully acquires the lock.
Thread Thread-0 begins processing business logic ...
Thread Thread-1 trying to get lock ...
Thread Thread-1 attempt to acquire a lock failed, and the lock is occupied by thread Thread-0.
Thread Thread-2 trying to get lock ...
Thread Thread-2 attempt to acquire a lock failed, and the lock is occupied by thread Thread-0.
Thread Thread-0 Start release lock ...
Start Delete root node/tmp_root_path ...
Thread Thread-0 successfully released the lock.
Root node/tmp_root_path deleted successfully. Release zookeeper connection succeeded.
The example may be slightly coarse, but this is the general principle. We can use the node in the last fixed position of zookeeper to determine if the lock was acquired. When a thread is temporary, if the node does not exist, no other threads occupy the corresponding lock, and the Create () method of the zookeeper creates the node, identifying that the distributed lock has been consumed by the current thread. After the business process is finished, call Zookeeper's Delete () method to delete the node, then complete the release of the lock.

At the same time, we can identify thread-unique fields that correspond to the node's write thread name, identifying which thread is taking up the lock. And when the thread to acquire the lock, if the lock is non-reentrant, regardless of which threads, even the thread holding the lock itself, you have to wait for the lock to be released and then acquire the lock, if it is a reentrant lock, then determine whether the current thread uniqueness field and the data in the corresponding node is consistent.

Of course, you can also use Zookeeper's createmode in Persistent_sequential, a sequential auto-numbered directory node, to detect a node subdirectory, to achieve the priority lock can be queued. This will be left to us for further study.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.