分布式锁实现两种方式

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;

}

/**

* 检查节点是否存在

* @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;

}

/**

* 创建节点

* @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;

}

/**

* 设置具有序列化的临时节点

* @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;

}

/**

* 删除节点

* @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;

}

/**

* 修改节点值

* @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);

}

}

/**

* 分布式锁 方式1 

* @param client

* @param path

* @param val

*/

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

boolean result = false;

// 首先查看节点是否存在

Stat stat = checkNode(client, path);

if (null == stat) {

// 创建节点

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

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

// 创建节点成功

InterProcessMutex lock = new InterProcessMutex(client, path);

try {

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

// 业务逻辑内容。。。。。。。

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;

}

/** 分布式锁 方式2

* 1.当商品抢购时,把抢购商品的 发布数量和购买数量传入,当用户支付前执行disLockNum 方法在zookeeper中记录用户已经准备支付的商品数量,

* 2.当发布商品修改商品数量时,设置zookeeper 中数量为0

* 3.支付失败时,从zookeeper中减去支付失败的商品数量;

* @param client

* @param path

* @param num:购买数量

* @param releaseNum:剩余数量

* @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)) {

// 首先查看节点是否存在

Stat stat = checkNode(client, path);

if (null == stat) {

// 创建节点

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

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

try {

result = true;

} catch (Exception e) {

e.printStackTrace();

}

}

}else{

//获取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{

//操作失败

return false;

}

}else{

//库存不足

return false;

}

}

}

}

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

lock.release();

} catch (Exception e) {

e.printStackTrace();

}

}

return result;

}

/**

* 支付失败后,把购买数量从zookeeper中去除

* @param client

* @param path

* @param num 减少的数量

* @return

*/

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

boolean result = false;

//获取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;

}

}

测试代码:

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; //购买数量

double storeNum = 2000;//发布数量

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; //开始支付货款

}

if(!pay){

//支付失败时

node.disLockProductdReduceNum(client, path, num);

}

if(null != client){

client.close();

}

if(step >1990){

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

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

}

}

});

}

}

}

猜你喜欢

转载自gjp014.iteye.com/blog/2363565