|
|
@ -22,26 +22,31 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
import java.util.concurrent.locks.Condition;
|
|
|
|
import java.util.concurrent.locks.Condition;
|
|
|
|
import java.util.concurrent.locks.Lock;
|
|
|
|
import java.util.concurrent.locks.Lock;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.redisson.core.RObject;
|
|
|
|
|
|
|
|
|
|
|
|
import com.lambdaworks.redis.RedisConnection;
|
|
|
|
import com.lambdaworks.redis.RedisConnection;
|
|
|
|
import com.lambdaworks.redis.pubsub.RedisPubSubAdapter;
|
|
|
|
import com.lambdaworks.redis.pubsub.RedisPubSubAdapter;
|
|
|
|
import com.lambdaworks.redis.pubsub.RedisPubSubConnection;
|
|
|
|
import com.lambdaworks.redis.pubsub.RedisPubSubConnection;
|
|
|
|
|
|
|
|
|
|
|
|
public class RedissonLock implements Lock {
|
|
|
|
// TODO make it reentrant
|
|
|
|
|
|
|
|
public class RedissonLock implements Lock, RObject {
|
|
|
|
|
|
|
|
|
|
|
|
private final CountDownLatch subscribeLatch = new CountDownLatch(1);
|
|
|
|
private final Redisson redisson;
|
|
|
|
private final RedisPubSubConnection<Object, Object> pubSubConnection;
|
|
|
|
private final RedisPubSubConnection<Object, Object> pubSubConnection;
|
|
|
|
private final RedisConnection<Object, Object> connection;
|
|
|
|
private final RedisConnection<Object, Object> connection;
|
|
|
|
|
|
|
|
|
|
|
|
private final String groupName = "redisson_lock_";
|
|
|
|
private final String groupName = "redisson_lock";
|
|
|
|
private final String name;
|
|
|
|
private final String name;
|
|
|
|
|
|
|
|
|
|
|
|
private static final Integer unlockMessage = 0;
|
|
|
|
private static final Integer unlockMessage = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final CountDownLatch subscribeLatch = new CountDownLatch(1);
|
|
|
|
private final AtomicBoolean subscribeOnce = new AtomicBoolean();
|
|
|
|
private final AtomicBoolean subscribeOnce = new AtomicBoolean();
|
|
|
|
|
|
|
|
|
|
|
|
private final Semaphore msg = new Semaphore(1);
|
|
|
|
private final Semaphore msg = new Semaphore(1);
|
|
|
|
|
|
|
|
|
|
|
|
RedissonLock(RedisPubSubConnection<Object, Object> pubSubConnection, RedisConnection<Object, Object> connection, String name) {
|
|
|
|
RedissonLock(Redisson redisson, RedisPubSubConnection<Object, Object> pubSubConnection, RedisConnection<Object, Object> connection, String name) {
|
|
|
|
|
|
|
|
this.redisson = redisson;
|
|
|
|
this.pubSubConnection = pubSubConnection;
|
|
|
|
this.pubSubConnection = pubSubConnection;
|
|
|
|
this.connection = connection;
|
|
|
|
this.connection = connection;
|
|
|
|
this.name = name;
|
|
|
|
this.name = name;
|
|
|
@ -49,6 +54,8 @@ public class RedissonLock implements Lock {
|
|
|
|
|
|
|
|
|
|
|
|
public void subscribe() {
|
|
|
|
public void subscribe() {
|
|
|
|
if (subscribeOnce.compareAndSet(false, true)) {
|
|
|
|
if (subscribeOnce.compareAndSet(false, true)) {
|
|
|
|
|
|
|
|
msg.acquireUninterruptibly();
|
|
|
|
|
|
|
|
|
|
|
|
RedisPubSubAdapter<Object, Object> listener = new RedisPubSubAdapter<Object, Object>() {
|
|
|
|
RedisPubSubAdapter<Object, Object> listener = new RedisPubSubAdapter<Object, Object>() {
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
@ -107,17 +114,14 @@ public class RedissonLock implements Lock {
|
|
|
|
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
|
|
|
|
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
|
|
|
|
time = unit.toMillis(time);
|
|
|
|
time = unit.toMillis(time);
|
|
|
|
while (!tryLock()) {
|
|
|
|
while (!tryLock()) {
|
|
|
|
|
|
|
|
if (time <= 0) {
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
long current = System.currentTimeMillis();
|
|
|
|
long current = System.currentTimeMillis();
|
|
|
|
// waiting for message
|
|
|
|
// waiting for message
|
|
|
|
boolean res = msg.tryAcquire(time, TimeUnit.MILLISECONDS);
|
|
|
|
msg.tryAcquire(time, TimeUnit.MILLISECONDS);
|
|
|
|
if (res) {
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
long elapsed = System.currentTimeMillis() - current;
|
|
|
|
long elapsed = System.currentTimeMillis() - current;
|
|
|
|
time -= elapsed;
|
|
|
|
time -= elapsed;
|
|
|
|
if (time <= 0) {
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -133,4 +137,19 @@ public class RedissonLock implements Lock {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public String getName() {
|
|
|
|
|
|
|
|
return name;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void destroy() {
|
|
|
|
|
|
|
|
pubSubConnection.unsubscribe(getChannelName());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
connection.close();
|
|
|
|
|
|
|
|
pubSubConnection.close();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
redisson.remove(this);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|