新增:trylock 尝试获取锁,并立即返回加锁结果

This commit is contained in:
绝尘 2023-10-21 13:00:55 +08:00
parent e1581f8cff
commit 747b165e77
2 changed files with 44 additions and 26 deletions

View File

@ -2,10 +2,11 @@ package net.tccn.zhub;
// ================================================== lock ================================================== // ================================================== lock ==================================================
public class Lock { public class Lock {
private String name; protected String name;
private String uuid; protected String uuid;
private int duration; protected int duration;
private ZHubClient hubClient; protected boolean success;
protected ZHubClient hubClient;
protected Lock(String name, String uuid, int duration, ZHubClient hubClient) { protected Lock(String name, String uuid, int duration, ZHubClient hubClient) {
this.name = name; this.name = name;
@ -17,4 +18,8 @@ public class Lock {
public void unLock() { public void unLock() {
hubClient.send("unlock", name, uuid); hubClient.send("unlock", name, uuid);
} }
public boolean success() {
return success;
}
} }

View File

@ -18,10 +18,7 @@ import java.io.OutputStream;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException; import java.net.SocketException;
import java.util.HashMap; import java.util.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
@ -162,11 +159,24 @@ public class ZHubClient extends AbstractConsumer implements IConsumer, IProducer
Lock lock = lockTag.get(value); Lock lock = lockTag.get(value);
if (lock != null) { if (lock != null) {
synchronized (lock) { synchronized (lock) {
lock.success = true;
lock.notifyAll(); lock.notifyAll();
} }
} }
continue; continue;
} }
// trylock msg
if ("trylock".equals(topic)) {
Lock lock = lockTag.get(value);
if (lock != null) {
synchronized (lock) {
lock.success = false;
lock.notifyAll();
}
}
continue;
}
// rpc back msg // rpc back msg
if (APP_NAME.equals(topic)) { if (APP_NAME.equals(topic)) {
rpcBackQueue.add(Event.of(topic, value)); rpcBackQueue.add(Event.of(topic, value));
@ -422,7 +432,7 @@ public class ZHubClient extends AbstractConsumer implements IConsumer, IProducer
send("auth", auth); send("auth", auth);
send("groupid " + groupid); send("groupid " + groupid);
StringBuffer buf = new StringBuffer("subscribe lock"); StringBuffer buf = new StringBuffer("subscribe lock trylock");
if (mainHub.containsValue(this)) { if (mainHub.containsValue(this)) {
buf.append(" " + APP_NAME); buf.append(" " + APP_NAME);
} }
@ -527,32 +537,35 @@ public class ZHubClient extends AbstractConsumer implements IConsumer, IProducer
// ================================================== lock ================================================== // ================================================== lock ==================================================
private Map<String, Lock> lockTag = new ConcurrentHashMap<>(); private Map<String, Lock> lockTag = new ConcurrentHashMap<>();
/**
* 尝试加锁立即返回
*
* @param key
* @param duration
* @return Lock: lock.success 锁定是否成功标识
*/
public Lock tryLock(String key, int duration) { public Lock tryLock(String key, int duration) {
String uuid = Utility.uuid(); return lock("trylock", key, duration);
Lock lock = new Lock(key, uuid, duration, this);
lockTag.put(uuid, lock);
try {
// c.send("lock", key, uuid, strconv.Itoa(duration))
send("lock", key, uuid, String.valueOf(duration));
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return lock;
} }
// 为替换 tryLock 方法做过度准确
public Lock lock(String key, int duration) { public Lock lock(String key, int duration) {
String uuid = Utility.uuid(); return lock("lock", key, duration);
}
/**
* @param cmd lock|trylock
* @param key 加锁 key
* @param duration 锁定时长
* @return
*/
private Lock lock(String cmd, String key, int duration) {
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
Lock lock = new Lock(key, uuid, duration, this); Lock lock = new Lock(key, uuid, duration, this);
lockTag.put(uuid, lock); lockTag.put(uuid, lock);
try { try {
// c.send("lock", key, uuid, strconv.Itoa(duration)) // c.send("lock", key, uuid, strconv.Itoa(duration))
send("lock", key, uuid, String.valueOf(duration)); send(cmd, key, uuid, String.valueOf(duration));
synchronized (lock) { synchronized (lock) {
lock.wait(); lock.wait();
} }