Distributed locks are implemented in two ways

package org.gjp;

 

import java.util.List;

import java.util.concurrent.TimeUnit;

 

import org.apache.curator.framework.CuratorFramework;

import org.apache.curator.framework.api.ExistsBuilder;

import org.apache.curator.framework.recipes.locks.InterProcessMutex;

import org.apache.zookeeper.CreateMode;

import org.apache.zookeeper.data.Stat;

 

public class ZkCreateNode {

 

 

public byte[] getData(CuratorFramework client,final String path){

byte [] b = null;

try {

b = client.getData().forPath(path);

} catch (Exception e) {

e.printStackTrace ();

}

 

return b;

}

 

/**

* Check if the node exists

* @param client

* @param path

* @return

*/

public Stat checkNode (CuratorFramework client, String path) {

ExistsBuilder eb = client.checkExists();

Stat stat = null;

try {

stat = eb.forPath(path);

if (stat != null) {

//System.out.println(stat);

System.out.println("version:" + stat.getVersion());

} else {

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

}

} catch (Exception e) {

e.printStackTrace ();

}

 

return stat;

}

 

/**

* create node

* @param client

* @param path

* @return

*/

public String createNode(CuratorFramework client, final String path, final String value) {

String result = "";

try {

result = client.create().forPath(path, value.getBytes());

System.out.println("res:" + result);

} catch (Exception e) {

e.printStackTrace ();

}

return result;

}

 

/**

* Set up a temporary node with serialization

* @param client

* @param path

* @param value

* @return

*/

public String createModeEphSeqNode(CuratorFramework client, final String path, final String value) {

String result = "";

try {

result = client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path, value.getBytes());

System.out.println("res:" + result);

} catch (Exception e) {

e.printStackTrace ();

}

return result;

}

 

/**

* delete node

* @param client

* @param path

* @return

*/

public boolean deleteNode(CuratorFramework client, final String path) {

boolean result = true;

try {

client.delete().forPath(path);

} catch (Exception e) {

result = false;

e.printStackTrace ();

}

 

return result;

}

 

/**

* Modify node value

* @param client

* @param path

* @param val

* @return

*/

public boolean changeNodeData(CuratorFramework client, final String path, final String val) {

boolean result = true;

try {

client.setData().forPath(path, val.getBytes());

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace ();

}

 

return result;

}

 

public void getNodeChild(CuratorFramework client, final String path) throws Exception {

List<String> pathChild = client.getChildren().forPath(path);

for (String item : pathChild) {

System.out.println("child:" + item);

}

 

}

 

/**

* Distributed lock mode 1 

* @param client

* @param path

* @param val

*/

public boolean disLock(CuratorFramework client, final String path, final String val) {

boolean result = false;

// First check if the node exists

Stat stat = checkNode (client, path);

if (null == stat) {

// create node

String res = createNode(client, path, val);

if (null != res && "".equals(res.trim())) {

// create node successfully

InterProcessMutex lock = new InterProcessMutex(client, path);

try {

if (lock.acquire(10 * 1000, TimeUnit.SECONDS)) {

 

// Business logic content. . . . . . .

System.out.println(Thread.currentThread().getName() + " hold lock");

Thread.sleep(5000L);

System.out.println(Thread.currentThread().getName() + " release lock");

 

result = true;

}

 

} catch (Exception e) {

e.printStackTrace ();

} finally {

try {

lock.release();

} catch (Exception e) {

e.printStackTrace ();

}

}

}

}

 

return result;

}

 

 

/** Distributed lock mode 2

* 1. When the product is snapped up, enter the release quantity and purchase quantity of the snapped up product, and execute the disLockNum method before the user pays to record the number of goods the user has prepared to pay in zookeeper.

* 2. When a product is published to modify the number of products, set the number in zookeeper to 0

* 3. When the payment fails, subtract the number of failed payment items from zookeeper;

* @param client

* @param path

* @param num: purchase quantity

* @param releaseNum: Remaining quantity

* @return

*/

public boolean disLockProductAddNum(CuratorFramework client, final String path, final Double num, final Double releaseNum) {

boolean result = false;

 

InterProcessMutex lock = new InterProcessMutex(client, path);

try {

if (lock.acquire(100 * 1000, TimeUnit.SECONDS)) {

 

// First check if the node exists

Stat stat = checkNode (client, path);

if (null == stat) {

// create node

String res = createNode(client, path, num.toString());

if (null != res && "".equals(res.trim())) {

try {

result = true;

 

} catch (Exception e) {

e.printStackTrace ();

}

}

}else{

//Get the number in zookeeper

byte[] preNum = getData(client, path);

if(null != preNum){

Double preTotal = 0.0;

if(preNum.length >0){

preTotal = Double.parseDouble(new String(preNum));

}

Double total = preTotal.doubleValue() + num.doubleValue();

if(total.doubleValue() < releaseNum.doubleValue()){

boolean b = changeNodeData(client, path, total.toString());

if(b){

result = true;

return result;

}else{

//operation failed

return false;

}

 

}else{

//Inventory shortage

return false;

}

 

}

 

 

}

 

}

} catch (Exception e) {

e.printStackTrace ();

} finally {

try {

lock.release();

} catch (Exception e) {

e.printStackTrace ();

}

}

return result;

 

}

 

 

/**

* After the payment fails, remove the purchase quantity from zookeeper

* @param client

* @param path

* @param num the amount to reduce

* @return

*/

public boolean disLockProductdReduceNum(CuratorFramework client, final String path, final Double num) {

boolean result = false;

 

//Get the number in zookeeper

byte[] preNum = getData(client, path);

if(null != preNum){

Double preTotal = 0.0;

if(preNum.length >0){

preTotal = Double.parseDouble(new String(preNum));

Double total = preTotal.doubleValue() - num.doubleValue();

if(total.doubleValue() >=0){

boolean b = changeNodeData(client, path, total.toString());

if(b){

result = true;

return result;

}

}

}

 

}

 

 

return result;

}

 

}

 

 

 

Test code:

 

package org.gjp;

 

import java.util.Calendar;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

 

import org.apache.curator.framework.CuratorFramework;

 

public class ProductNumThread {

 

public static void main(String[] args) {

 

ExecutorService exe = Executors.newFixedThreadPool(70);

final long start =Calendar.getInstance().getTimeInMillis();

for (int i = 1; i < 1990; i++) {

final double step = i;

final double iN = 1;

exe.execute(new Runnable() {

double num = iN; //buy quantity

double storeNum = 2000;//Number of releases

String path ="/orage_id"; //商品id

public void run() {

CuratorFramework client = ZkListenTest.getClient();

ZkCreateNode node = new ZkCreateNode();

boolean flag = node.disLockProductAddNum(client, path, num, storeNum);

System.out.println("flag:"+flag);

 

boolean pay = false;

if(flag){

pay = true; //Start to pay for goods

 

}

 

if(!pay){

// when payment fails

node.disLockProductdReduceNum(client, path, num);

}

 

if(null != client){

client.close();

}

if(step >1990){

long end = Calendar.getInstance().getTimeInMillis();

System.out.println("==========================="+(end -start));

}

}

});

}

 

}

 

}

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326605715&siteId=291194637