手写zookeeper分布式锁,测试生成订单编号
1.生成订单编号工具类
/** * Todo * * @author CSD * @date 2021-09-09 13:51 * 订单编号工具类 */ public class OrderNumCreateUtil { private static int number = 0; /** * 生成订单编号 * @return */ public String getNumber(){ return String.valueOf(++number); } }
2.订单业务类
/** * Todo * 订单业务类 * @author CSD * @date 2021-09-09 13:54 */ public class OrderService { private OrderNumCreateUtil orderNumCreateUtil = new OrderNumCreateUtil(); private ZkLock zkLock = new ZkdistributedLock(); public void getordNumber() { zkLock.zklock(); try { String number = orderNumCreateUtil.getNumber(); System.out.println("number = " + number); }catch (Exception e){ e.printstacktrace(); }finally { zkLock.zkUnlock(); } } }
3.zookeeper接口
/** * Todo * * @author CSD * @date 2021-09-09 14:05 */ public interface ZkLock { public void zklock(); public void zkUnlock(); }
4. 使用模板设计模式把共用的代码抽离父类
/** * Todo * * @author CSD * @date 2021-09-09 14:07 */ public abstract class ZkAbstractTemplateLock implements ZkLock { protected String path = "/zkLock"; protected CountDownLatch countDownLatch = null; public static final String ZKSERVER = "172.22.83.153:2181"; public static final Integer TIME_OUT = 45 * 1000; ZkClient zkClient = new ZkClient(ZKSERVER,TIME_OUT); @Override public void zklock() { if(tryZkLock()){ System.out.println("线程"+Thread.currentThread().getName()+":获得锁\n"); }else{ waitZkLock(); zklock(); } } public abstract void waitZkLock(); public abstract boolean tryZkLock(); @Override public void zkUnlock() { if (zkClient != null){ zkClient.close(); } System.out.println("线程"+Thread.currentThread().getName()+"释放锁\n\n"); } }
5.zk分布式锁具体的实现类
/** * Todo * * @author CSD * @date 2021-09-09 14:22 */ public class ZkdistributedLock extends ZkAbstractTemplateLock{ @Override public void waitZkLock() { IZkDataListener iZkDataListener = new IZkDataListener() { @Override public void handleDataChange(String dataPath, Object data) { } @Override public void handleDataDeleted(String dataPath){ 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); } @Override public boolean tryZkLock() { try { zkClient.createEphemeral(path); return true; } catch (Exception e){ return false; } } }
6.开启10个线程测试
/** * Todo * * @author CSD * @date 2021-09-09 13:57 */ public class Client { public static void main(String[] args) { for (int i = 0; i < 50; i++) { new Thread(()->{ new OrderService().getordNumber(); },String.valueOf(i)).start(); } } }
7.运行结果
线程6:获得锁 number = 1 线程6释放锁 线程1:获得锁 number = 2 线程1释放锁 线程5:获得锁 number = 3 线程5释放锁 线程8:获得锁 number = 4 线程8释放锁 线程2:获得锁 number = 5 线程2释放锁 线程4:获得锁 number = 6 线程4释放锁 线程0:获得锁 number = 7 线程0释放锁 线程7:获得锁 number = 8 线程7释放锁 线程3:获得锁 number = 9 线程3释放锁 线程9:获得锁 number = 10 线程9释放锁
8.所用的maven依赖
<dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。