实现过程:
首先,一个线程获取锁并调用方法生成订单号,在该线程未释放锁资源时,其他线程会被
countDownLatch阻塞,直到该线程释放锁资源。
实现模拟并发生成订单号功能
代码实现:
先导入一个依赖
com.101tec zkclient0.10
Lock接口:
package com.doll.zookeeperlock; public interface Lock { void getLock(); void unLock(); }
ZookeeperAbstractLock抽象类并实现Lock
package com.doll.zookeeperlock; import org.I0Itec.zkclient.ZkClient; import java.util.concurrent.CountDownLatch; public abstract class ZookeeperAbstractLock implements Lock{ private static final String ConNECTSTRING="linuxIP地址:zookeeper端口"; // zookeeper地址 protected ZkClient zkClient=new ZkClient(CONNECTSTRING); // 连接zookeeper protected static String PATH="/lock"; // 创建节点路径 protected CountDownLatch countDownLatch; // 倒计时器作用线程阻塞 @Override public void getLock() { if(tryLock()){ System.out.println("---------------获取锁成功---------------"); }else { waitLock(); getLock(); //自己调自己 } } @Override public void unLock() { if(zkClient!=null){ zkClient.close(); System.out.println("---------------释放资源---------------"); } } public abstract boolean tryLock(); public abstract void waitLock(); }
OrderNumGenerator订单号生成类:
package com.doll.zookeeperlock; import java.text.SimpleDateFormat; import java.util.Date; public class OrderNumGenerator { //组成订单号的变量 private static int count = 0; public String getNumber() { SimpleDateFormat simpt = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); //时间类型转化 return simpt.format(new Date()) + "-" + ++count; } }
ZookeeperDistrbuteLock继承并实现分布式锁
package com.doll.zookeeperlock; import org.I0Itec.zkclient.IZkDataListener; import java.util.concurrent.CountDownLatch; public class ZookeeperDistrbuteLock extends ZookeeperAbstractLock { public boolean tryLock() { try { //创建临时节点成功,返回true zkClient.createEphemeral(PATH); return true; } catch (Exception e) { return false; } } public void waitLock() { // 使用事件监听,获取到节点被删除 IZkDataListener iZkDataListener = new IZkDataListener(){ public void handleDataChange(String s, Object o) throws Exception { } public void handleDataDeleted(String s) throws Exception { if(countDownLatch!=null){ countDownLatch.countDown(); } } }; zkClient.subscribeDataChanges(PATH,iZkDataListener); if(zkClient.exists(PATH)){ countDownLatch=new CountDownLatch(1); try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } zkClient.unsubscribeDataChanges(PATH,iZkDataListener); } }
OrderService,main方法类
package com.doll.zookeeperlock; //Runnable模拟并发编程 public class OrderService implements Runnable { private OrderNumGenerator orderNumGenerator = new OrderNumGenerator(); private Lock lock = new com.doll.zookeeperlock.ZookeeperDistrbuteLock(); public void run() { try { lock.getLock(); getNumber(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unLock(); } } public void getNumber(){ String orderNo = orderNumGenerator.getNumber(); System.out.println(Thread.currentThread().getName() + ",orderNo=======>:" + orderNo); } public static void main(String[] args) { System.out.println("--------------模拟生成订单号开始--------------"); for (int i = 1; i <10 ; i++) { new Thread(new OrderService()).start(); } } }
运行结果图
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)