Java实现分布式锁(模板设计模式+zk分布式锁+JUC精确唤醒+行锁效果)

大家好,之前写的一篇文章没有实现分布式锁的效果,这次写了个分布式锁,直接上代码,欢迎大家批评指正!

package com.hollycrm;

import org.I0Itec.zkclient.ZkClient;

abstract class DistributeAbstractLock {

private static String ZKSERVER_ADDRESS = "localhost:2181";

protected static int SERVER_TIMEOUT = 45*1000;

protected ZkClient zkClient = new ZkClient(ZKSERVER_ADDRESS , SERVER_TIMEOUT);

protected String zkpath = "/zkpath";

public void lock(String id){
    if(trylock(id)){
        System.out.println("线程 :"+ Thread.currentThread().getName() + " 拿到锁");
    }else{
        waitlock(id);

        lock(id);
    }
}

public void unlock(String id){
    if(zkClient!=null ){
        //zkClient.delete(zkpath);
        zkClient.delete(id);//相当于客户端quit命令
        System.out.println("线程 :"+ Thread.currentThread().getName() + " 释放锁成功");
    }
}

public abstract boolean trylock(String id);

public abstract void waitlock(String id);

}

import org.I0Itec.zkclient.IZkDataListener;
import java.util.concurrent.*;

public class DistributeZKLock extends DistributeAbstractLock {

private CountDownLatch countDownLatch = new CountDownLatch(1);

public boolean trylock(String id) {

    //if(!zkClient.exists(zkpath)){
    try {
        System.out.println("线程 :"+ Thread.currentThread().getName() + "尝试创建节点:"+ id);
        zkClient.createEphemeral(id);
        System.out.println("线程 :"+ Thread.currentThread().getName() + "创建节点:"+ id +"成功!");
        return true;
    } catch (Exception e) {
        System.out.println("线程 :"+ Thread.currentThread().getName() + "尝试创建节点:"+ id +"失败!");
        return false;
    }
}

public void waitlock(String id) {

    IZkDataListener iZkDataListener = new IZkDataListener() {
        public void handleDataChange(String s, Object o) throws Exception {

        }

        public void handleDataDeleted(String s) throws Exception {
            System.out.println("线程 :"+ Thread.currentThread().getName() + "感知到zk节点发生变化,阻塞线程即将被唤醒!");
                countDownLatch.countDown();
        }
    };

    zkClient.subscribeDataChanges(id , iZkDataListener);
    System.out.println("线程 :"+ Thread.currentThread().getName() + "进入waitlock方法,注册监听!监听节点 :" + id);

    if(zkClient.exists(id)){

        try {
            //cyclicBarrier.await(SERVER_TIMEOUT , TimeUnit.MILLISECONDS);
            System.out.println("线程 :"+ Thread.currentThread().getName() + "即将进入阻塞状态!");
            countDownLatch.await(SERVER_TIMEOUT , TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

}

package com.hollycrm;

import com.hollycrm.service.OrderService;

public class MyThread implements Runnable {

private DistributeZKLock zkLock ;

private OrderService orderService;

private String id;

public MyThread(DistributeZKLock zkLock, OrderService orderService, String id) {
    this.zkLock = zkLock;
    this.orderService = orderService;
    this.id = id;
}

public void run() {

    zkLock.lock(id);

    try{
        System.out.println("线程 :"+ Thread.currentThread().getName() + " 执行业务逻辑");

        String order = orderService.createOrder();
        System.out.println("线程 :"+ Thread.currentThread().getName() + "生成订单号 :" + order);
    }finally {
        zkLock.unlock(id);
    }
}

}

package com.hollycrm;

import com.hollycrm.service.OrderService;

import javax.print.Doc;
import java.util.ArrayList;

public class Test {

public static void main(String[] args) {

    DistributeZKLock zkLock = new DistributeZKLock();

    OrderService orderService = new OrderService();
    OrderService orderService1 = new OrderService();

    ArrayList<MyThread> list = new ArrayList<MyThread>();
    ArrayList<MyThread> list1 = new ArrayList<MyThread>();

    for (int i = 0; i < 50; i++) {
        list.add(new MyThread(zkLock , orderService,"/lock1"));
    }
    for (int i = 0; i < 50; i++) {
        list.add(new MyThread(zkLock , orderService,"/lock2"));
    }
    for (int i = 0; i < 50; i++) {
        list1.add(new MyThread(zkLock , orderService1,"/lock3"));
    }
    for (int i = 0; i < 50; i++) {
        list1.add(new MyThread(zkLock , orderService1,"/lock4"));
    }

    for (int i = 0; i < 100; i++) {
        new Thread(list.get(i)).start();
        new Thread(list1.get(i)).start();
    }

}

}

在这里插入图片描述

有对大数据感兴趣的小伙伴 欢迎来交流经验!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值