1、使用zookeeper API实现分布式锁
DistributedLock.java
import java.io.IOException;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
public class DistributedLock implements Lock,Watcher{
private ZooKeeper zk = null;
private String ROOT_LOCK = "/locks003";//定义根节点
private String WAIT_LOCK;//等待前一个锁
private String CURRENT_LOCK;//表示当前的锁
private CountDownLatch countDownLatch;
public DistributedLock() {
try {
zk = new ZooKeeper("192.168.1.102:2181,192.168.1.102:2182,192.168.1.102:2183",4000,this);
// 判断根节点是否存在
Stat stat = zk.exists(ROOT_LOCK, false);
if(stat == null) {
zk.create(ROOT_LOCK, "0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
} catch (IOException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public boolean tryLock() {
try {
// 创建临时有序节点
CURRENT_LOCK = zk.create(ROOT_LOCK + "/" , "0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
System.out.println(Thread.currentThread().getName() + "->" + CURRENT_LOCK + " try lock ");
List<String> childrens = zk.getChildren(ROOT_LOCK, false);
SortedSet<String> sortedSet = new TreeSet();//定义一个集合进行排序
for(String children : childrens) {
sortedSet.add(ROOT_LOCK + "/" + children);
}
String firstNode = sortedSet.first();//获得当前所有子节点中最小的节点
SortedSet<String> lessThenMe = ((TreeSet<String>)sortedSet).headSet(CURRENT_LOCK);
// 如果当前节点和集合中的最小节点相同,表示获得锁
if(CURRENT_LOCK.equals(firstNode)) {
return true;
}
if(!lessThenMe.isEmpty()) {
// 获得比当前节点更小的最后一个节点,设置给WAIT_LOCK
WAIT_LOCK = lessThenMe.last();
}
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
return false;
}
@Override
public void process(WatchedEvent event) {
if(this.countDownLatch != null) {
this.countDownLatch.countDown();
}
}
@Override
public void lock() {
if(this.tryLock()) {
System.out.println(Thread.currentThread().getName() + "->" + CURRENT_LOCK + "->" + " get lock success " );
return;
}
try {
waitForLock(WAIT_LOCK);//没有获得锁,继续等待获得锁
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private boolean waitForLock(String prev) throws KeeperException, InterruptedException {
Stat stat = zk.exists(prev, true);//监听当前节点的上一个节点
if(stat != null) {
System.out.println(Thread.currentThread().getName() + " -> wait lock " + prev + " 释放 ");
countDownLatch = new CountDownLatch(1);
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + " -> get lock success -- / -- ");
}
return true;
}
@Override
public void lockInterruptibly() throws InterruptedException {
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public void unlock() {
System.out.println(Thread.currentThread().getName() + " 释放锁 " + CURRENT_LOCK);
try {
zk.delete(CURRENT_LOCK, -1);
CURRENT_LOCK = null;
zk.close();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
}
}
@Override
public Condition newCondition() {
return null;
}
}
测试程序:DistributedLockTest.java
public class DistributedLockTest {
public static void main(String[] args) throws IOException {
final CountDownLatch countDownLatch = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
Thread thread =new Thread(new Runnable() {
@Override
public void run() {
try {
countDownLatch.await();
DistributedLock distributedLock = new DistributedLock();
distributedLock.lock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"Thread-" + i);
thread.start();
countDownLatch.countDown();
}
System.in.read();
}
}
2、使用Curator客户端实现分布式锁
参考:Apache Curator+Zookeeper 实现分布式锁 入门篇
来源:oschina
链接:https://my.oschina.net/u/4405256/blog/4572281