赞
踩
- <dependency>
- <groupId>com.101tec</groupId>
- <artifactId>zkclient</artifactId>
- <version>0.10</version>
- </dependency>
- 如果有一把锁,被多个人给竞争,此时多个人会排队,第一个拿到锁的人会执行,然后释放锁;后面的每个人都会去监听**排在自己前面**的那个人创建的 node 上,一旦某个人释放了锁,排在自己后面的人就会被 zookeeper 给通知,一旦被通知了之后,就 ok 了,自己就获取到了锁,就可以执行代码了。
- ```java
- public class ZooKeeperDistributedLock {
-
- //private ZooKeeper zk;
- private ZkClient zk;
- private String locksRoot = "/locks";
- private String productId;
- private String waitNode;
- private String lockNode;
- private CountDownLatch latch;
- private int sessionTimeout = 30000;
-
- public ZooKeeperDistributedLock() {
-
- try {
-
- String address="192.168.31.187:2181,192.168.31.19:2181,192.168.31.227:2181";
- zk = new ZkClient(address, sessionTimeout, sessionTimeout);
- } catch (IOException e) {
- throw new LockException(e);
- } catch (KeeperException e) {
- throw new LockException(e);
- } catch (InterruptedException e) {
- throw new LockException(e);
- }
- }
-
-
- public void acquireDistributedLock() {
- try {
- if (this.tryLock()) {
- return;
- } else {
- waitForLock(waitNode, sessionTimeout);
- acquireDistributedLock();
- }
- } catch (KeeperException e) {
- throw new LockException(e);
- } catch (InterruptedException e) {
- throw new LockException(e);
- }
- }
-
- public boolean tryLock() {
- try {
-
- lockNode = this.client.createEphemeralSequential(locksRoot+ "/", "1");
-
- // 看看刚创建的节点是不是最小的节点
- // locks:10000000000,10000000001,10000000002
- List<String> locks = zk.getChildren(locksRoot);
- Collections.sort(locks);
-
- if(lockNode.equals(locksRoot+"/"+ locks.get(0))){
- System.out.println(Thread.currentThread().getName() + ":获取锁成功");
- //如果是最小的节点,则表示取得锁
- return true;
- }
-
- //如果不是最小的节点,找到比自己小1的节点
- int previousLockIndex = -1;
- for(int i = 0; i < locks.size(); i++) {
- if(lockNode.equals(locksRoot + “/” + locks.get(i))) {
- previousLockIndex = i - 1;
- break;
- }
- }
-
- this.waitNode = locks.get(previousLockIndex);
- } catch (KeeperException e) {
- throw new LockException(e);
- } catch (InterruptedException e) {
- throw new LockException(e);
- }
- return false;
- }
-
- private boolean waitForLock(String waitNode, long waitTime) throws
- InterruptedException, KeeperException {
- Stat stat = zk.exists(locksRoot + "/" + waitNode, true);
- this.latch = new CountDownLatch(1);
-
- IZkDataListener listener = new IZkDataListener() {
- @Override
- public void handleDataChange(String arg0, Object arg1) throws Exception {
- }
- @Override
- public void handleDataDeleted(String arg0)
- throws Exception {
- System.out.println("节点被删除了,开始抢锁");
- cdl.countDown();
- }
- };
-
- // 完成watcher注册
- this.client.subscribeDataChanges(beforePath, listener);
-
- if (stat != null) {
- this.latch.await(waitTime, TimeUnit.MILLISECONDS);
- this.latch = null;
- }
-
- // 取消注册
- this.client.unsubscribeDataChanges(beforePath, listener);
- return true;
- }
-
- public void unlock() {
- try {
- // 删除/locks/10000000000节点
- // 删除/locks/10000000001节点
- System.out.println("unlock " + lockNode);
- zk.delete(lockNode);
- System.out.println(Thread.currentThread().getName()
- + "所有锁释放成功:删除zk节点");
- lockNode = null;
- zk.close();
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (KeeperException e) {
- e.printStackTrace();
- }
- }
-
- public class LockException extends RuntimeException {
- private static final long serialVersionUID = 1L;
-
- public LockException(String e) {
- super(e);
- }
-
- public LockException(Exception e) {
- super(e);
- }
- }
- }
- public class OrderCodeGenerator {
-
- private int i = 0;
-
- public String getOrderCode() {
-
- Date now = new Date();
-
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-");
-
- return sdf.format(now) + ++i;
-
- }
- }
-
- public class OrderServiceImplWithZkDis implements OrderService {
-
-
- private static OrderCodeGenerator org = new OrderCodeGenerator();
-
-
- private Lock lock = new ZooKeeperDistributedLock();
-
-
- @Override
-
- public void createOrder() {
-
- String orderCode = null;
-
- try {
-
- lock.acquireDistributedLock();
-
- orderCode = org.getOrderCode();
-
- //TestReLock();
-
- System.out.println(Thread.currentThread().getName() + "生成订单:" + orderCode);
-
- } catch (Exception e) {
-
- e.printStackTrace();
-
- } finally {
-
- lock.unlock();
-
- }
-
- }
-
-
- /**
- public void TestReLock() {
-
- lock.acquireDistributedLock();
-
- System.out.println(Thread.currentThread().getName() + "测试重入锁成功...");
-
- lock.unlock();
-
- }
- **/
-
-
- public static void main(String[] args) {
-
- int num = 5;
-
- CyclicBarrier cyclicBarrier = new CyclicBarrier(num);
-
- for (int i = 0; i < num; i++) {
-
- new Thread(new Runnable() {
-
- @Override
-
- public void run() {
-
- OrderService orderService = new OrderServiceImplWithZkDis();
-
- System.out.println(Thread.currentThread().getName() + ": 我准备好了");
-
- try {
- cyclicBarrier.await();
-
- } catch (Exception e) {
-
- e.printStackTrace();
-
- }
-
- orderService.createOrder();
-
- }
-
- }).start();
-
- }
-
- }
-
- }
- Thread-2:我准备好了
- Thread-3:我准备好了
- Thread-1:我准备好了
- Thread-5:我准备好了
- Thread-4:我准备好了
- Thread-4:获取锁成功
- Thread-4生成订单:2018-07-12-13-12-09-1
- Thread-4所有锁释放成功:删除ZK节点
- 节点删除了,开始抢锁
- Thread-5:获取锁成功
- Thread-5生成订单:2018-07-12-13-12-11-2
- Thread-5所有锁释放成功:删除ZK节点
- 节点删除了,开始抢锁
- Thread-2:获取锁成功
- Thread-2生成订单:2018-07-12-13-12-14-3
- Thread-2所有锁释放成功:删除ZK节点
- 节点删除了,开始抢锁
- Thread-3:获取锁成功
- Thread-3生成订单:2018-07-12-13-12-17-4
- Thread-3所有锁释放成功:删除ZK节点
- 节点删除了,开始抢锁
- Thread-1:获取锁成功
- Thread-1生成订单:2018-07-12-13-12-21-5
- Thread-1所有锁释放成功:删除ZK节点
- 节点删除了,开始抢锁
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。