大家好,之前写的一篇文章没有实现分布式锁的效果,这次写了个分布式锁,直接上代码,欢迎大家批评指正!
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();
}
}
}
有对大数据感兴趣的小伙伴 欢迎来交流经验!