Scene Description
In high thread concurrency scenarios, generate a unique order number
Such as: 2017-10-14-20-52-33-01
Year, month, day, hour number
Case
Orders generated class
public class the OrderNumber { Private static Integer Number = 0 ; // generated order number public String the getNumber () { SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); ++number; return sdf.format(new Date())+"\t"+number; } }
Order processing business class
public class OrderService implements Runnable{ private static OrderNumber orderNumber=new OrderNumber(); private Lock lock=new ZkLockImpl(); // generate orders public void getOrderNumber () { // synchronized block: multiple threads to access the same resource / * the synchronized (the orderNumber) { }*/ // get lock Lock .getLock (); . System OUT .println ( " current generated order number is: " + orderNumber.getNumber ()); // release the lock Lock .unLock (); } @Override public void run() { getOrderNumber(); } public static void main (String [] args) { // generates threads 100 for ( int I = . 1 ; I <= 10000 ; I ++ ) { new new the Thread ( new new OrderService ()) Start ().; } } }
Lock Interface
public interface Lock { // Get lock public void a GETLOCK (); // release the lock public void unLock (); }
Lock implement interfaces
public abstract class ZookeeperLock implements Lock{ /** * Create a connection object zkClient */ private static final String ZK_ADDRESS="0.0.0.0:2181"; protected ZkClient zkClient=new ZkClient(ZK_ADDRESS); /** * Each process when creating a node, in fact, obtain a lock if the lock is found in obtaining the return value is true, does not represent the current lock, I can use, if the return value is false, on behalf of the lock being occupied, so I can only wait * @return */ @Override public void a GETLOCK () { // get a lock IF (tryLock ()) { . System OUT .println ( " get to lock resource " ); } The else { // When the return value is false, on behalf of the current lock is in use, wait waitLock (); // After waiting I have to get it again, again, I do not get how can I get a lock resources getLock (); } } /** * Release the lock, zk close */ @Override public void unLock() { if(zkClient!=null){ zkClient.close(); } } // get the resource lock public abstract boolean tryLock (); // wait for public abstract void waitLock (); }
Get the class and release locks realize the
public class ZkLockImpl extends ZookeeperLock{ private CountDownLatch countDownLatch = null; @Override public Boolean tryLock () { the try { // create a temporary node zkClient.createEphemeral ( " / zkTemp " ); return to true ; }catch (Exception ex){ return false; } } @Override public void waitLock () { // monitor whether the node is removed IZkDataListener iZkDataListener = new new IZkDataListener () { @Override public void handleDataChange(String s, Object o) throws Exception { } @Override public void handleDataDeleted(String s) throws Exception { if(countDownLatch!=null){ //释放掉 countDownLatch.countDown(); } } }; // If there has been zkTemp node waits IF (zkClient.exists ( " / zkTemp " )) { countDownLatch=new CountDownLatch(1); . System OUT .println ( " Order Number repeat, please wait ================================= " ); the try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace (); } } } }
Distributed Lock Solutions
Distributed Lock use zk, create a temporary node (valid) on zk, using a temporary node as a lock, because the nodes must be unique.
If you can successfully create a node to generate the order number, if you create a node fails, wait. Temporary node zk closed, the lock is released, the other nodes can re-generate the order number.