RedissonReadWriteLockTest added. #206
parent
0a577fed44
commit
c6255fa9b5
@ -0,0 +1,449 @@
|
|||||||
|
package org.redisson;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.redisson.core.RLock;
|
||||||
|
import org.redisson.core.RReadWriteLock;
|
||||||
|
|
||||||
|
public class RedissonReadWriteLockTest extends BaseConcurrentTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWriteLock() throws InterruptedException {
|
||||||
|
final RReadWriteLock lock = redisson.getReadWriteLock("lock");
|
||||||
|
|
||||||
|
final RLock writeLock = lock.writeLock();
|
||||||
|
writeLock.lock();
|
||||||
|
|
||||||
|
Assert.assertTrue(lock.writeLock().tryLock());
|
||||||
|
|
||||||
|
Thread t = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
Assert.assertFalse(writeLock.isHeldByCurrentThread());
|
||||||
|
Assert.assertTrue(writeLock.isLocked());
|
||||||
|
Assert.assertFalse(lock.readLock().tryLock());
|
||||||
|
Assert.assertFalse(redisson.getReadWriteLock("lock").readLock().tryLock());
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertTrue(lock.readLock().tryLock());
|
||||||
|
Assert.assertTrue(redisson.getReadWriteLock("lock").readLock().tryLock());
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
t.join(50);
|
||||||
|
|
||||||
|
writeLock.unlock();
|
||||||
|
Assert.assertFalse(lock.readLock().tryLock());
|
||||||
|
Assert.assertTrue(writeLock.isHeldByCurrentThread());
|
||||||
|
writeLock.unlock();
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
Assert.assertFalse(lock.writeLock().tryLock());
|
||||||
|
Assert.assertFalse(lock.writeLock().isLocked());
|
||||||
|
Assert.assertFalse(lock.writeLock().isHeldByCurrentThread());
|
||||||
|
lock.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiRead() throws InterruptedException {
|
||||||
|
final RReadWriteLock lock = redisson.getReadWriteLock("lock");
|
||||||
|
Assert.assertFalse(lock.delete());
|
||||||
|
|
||||||
|
final RLock readLock1 = lock.readLock();
|
||||||
|
readLock1.lock();
|
||||||
|
|
||||||
|
Assert.assertFalse(lock.writeLock().tryLock());
|
||||||
|
|
||||||
|
final AtomicReference<RLock> readLock2 = new AtomicReference<RLock>();
|
||||||
|
Thread t = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
RLock r = lock.readLock();
|
||||||
|
Assert.assertFalse(readLock1.isHeldByCurrentThread());
|
||||||
|
Assert.assertTrue(readLock1.isLocked());
|
||||||
|
r.lock();
|
||||||
|
readLock2.set(r);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
r.unlock();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
t.join(50);
|
||||||
|
|
||||||
|
Assert.assertTrue(readLock2.get().isLocked());
|
||||||
|
|
||||||
|
readLock1.unlock();
|
||||||
|
Assert.assertFalse(lock.writeLock().tryLock());
|
||||||
|
Assert.assertFalse(readLock1.isHeldByCurrentThread());
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
Assert.assertFalse(readLock2.get().isLocked());
|
||||||
|
Assert.assertTrue(lock.writeLock().tryLock());
|
||||||
|
Assert.assertTrue(lock.writeLock().isLocked());
|
||||||
|
Assert.assertTrue(lock.writeLock().isHeldByCurrentThread());
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
|
||||||
|
Assert.assertFalse(lock.writeLock().isLocked());
|
||||||
|
Assert.assertFalse(lock.writeLock().isHeldByCurrentThread());
|
||||||
|
Assert.assertTrue(lock.writeLock().tryLock());
|
||||||
|
lock.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDelete() {
|
||||||
|
RReadWriteLock lock = redisson.getReadWriteLock("lock");
|
||||||
|
Assert.assertFalse(lock.delete());
|
||||||
|
|
||||||
|
lock.readLock().lock();
|
||||||
|
Assert.assertTrue(lock.delete());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testForceUnlock() {
|
||||||
|
RReadWriteLock lock = redisson.getReadWriteLock("lock");
|
||||||
|
RLock readLock = lock.readLock();
|
||||||
|
readLock.lock();
|
||||||
|
Assert.assertTrue(readLock.isLocked());
|
||||||
|
readLock.forceUnlock();
|
||||||
|
Assert.assertFalse(readLock.isLocked());
|
||||||
|
|
||||||
|
lock = redisson.getReadWriteLock("lock");
|
||||||
|
Assert.assertFalse(lock.readLock().isLocked());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpireRead() throws InterruptedException {
|
||||||
|
RReadWriteLock lock = redisson.getReadWriteLock("lock");
|
||||||
|
lock.readLock().lock(2, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
final long startTime = System.currentTimeMillis();
|
||||||
|
Thread t = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
RReadWriteLock lock1 = redisson.getReadWriteLock("lock");
|
||||||
|
lock1.readLock().lock();
|
||||||
|
long spendTime = System.currentTimeMillis() - startTime;
|
||||||
|
Assert.assertTrue(spendTime < 2050);
|
||||||
|
lock1.readLock().unlock();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
t.join();
|
||||||
|
|
||||||
|
lock.readLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpireWrite() throws InterruptedException {
|
||||||
|
RReadWriteLock lock = redisson.getReadWriteLock("lock");
|
||||||
|
lock.writeLock().lock(2, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
final long startTime = System.currentTimeMillis();
|
||||||
|
Thread t = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
RReadWriteLock lock1 = redisson.getReadWriteLock("lock");
|
||||||
|
lock1.writeLock().lock();
|
||||||
|
long spendTime = System.currentTimeMillis() - startTime;
|
||||||
|
Assert.assertTrue(spendTime < 2050);
|
||||||
|
lock1.writeLock().unlock();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
t.join();
|
||||||
|
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAutoExpire() throws InterruptedException {
|
||||||
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
testSingleInstanceConcurrency(1, new RedissonRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run(RedissonClient redisson) {
|
||||||
|
RReadWriteLock lock1 = redisson.getReadWriteLock("lock");
|
||||||
|
lock1.writeLock().lock();
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||||
|
RReadWriteLock lock1 = redisson.getReadWriteLock("lock");
|
||||||
|
Thread.sleep(TimeUnit.SECONDS.toMillis(RedissonLock.LOCK_EXPIRATION_INTERVAL_SECONDS + 1));
|
||||||
|
Assert.assertFalse("Transient lock expired automatically", lock1.writeLock().isLocked());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHoldCount() {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
testHoldCount(rwlock.readLock());
|
||||||
|
testHoldCount(rwlock.writeLock());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testHoldCount(RLock lock) {
|
||||||
|
Assert.assertEquals(0, lock.getHoldCount());
|
||||||
|
lock.lock();
|
||||||
|
Assert.assertEquals(1, lock.getHoldCount());
|
||||||
|
lock.unlock();
|
||||||
|
Assert.assertEquals(0, lock.getHoldCount());
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
lock.lock();
|
||||||
|
Assert.assertEquals(2, lock.getHoldCount());
|
||||||
|
lock.unlock();
|
||||||
|
Assert.assertEquals(1, lock.getHoldCount());
|
||||||
|
lock.unlock();
|
||||||
|
Assert.assertEquals(0, lock.getHoldCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsHeldByCurrentThreadOtherThread() throws InterruptedException {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
lock.lock();
|
||||||
|
|
||||||
|
Thread t = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
|
||||||
|
Assert.assertFalse(lock.isHeldByCurrentThread());
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
t.join();
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
Thread t2 = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
|
||||||
|
Assert.assertFalse(lock.isHeldByCurrentThread());
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
t2.start();
|
||||||
|
t2.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsHeldByCurrentThread() {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
Assert.assertFalse(lock.isHeldByCurrentThread());
|
||||||
|
lock.lock();
|
||||||
|
Assert.assertTrue(lock.isHeldByCurrentThread());
|
||||||
|
lock.unlock();
|
||||||
|
Assert.assertFalse(lock.isHeldByCurrentThread());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsLockedOtherThread() throws InterruptedException {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
lock.lock();
|
||||||
|
|
||||||
|
Thread t = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
Assert.assertTrue(lock.isLocked());
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
t.join();
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
Thread t2 = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
Assert.assertFalse(lock.isLocked());
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
t2.start();
|
||||||
|
t2.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsLocked() {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
Assert.assertFalse(lock.isLocked());
|
||||||
|
lock.lock();
|
||||||
|
Assert.assertTrue(lock.isLocked());
|
||||||
|
lock.unlock();
|
||||||
|
Assert.assertFalse(lock.isLocked());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalMonitorStateException.class)
|
||||||
|
public void testUnlockFail() throws InterruptedException {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
Thread t = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
rwlock.readLock().lock();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
t.join();
|
||||||
|
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLockUnlock() {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
lock.lock();
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReentrancy() throws InterruptedException {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock");
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
|
||||||
|
Assert.assertTrue(lock.tryLock());
|
||||||
|
Assert.assertTrue(lock.tryLock());
|
||||||
|
lock.unlock();
|
||||||
|
// next row for test renew expiration tisk.
|
||||||
|
//Thread.currentThread().sleep(TimeUnit.SECONDS.toMillis(RedissonLock.LOCK_EXPIRATION_INTERVAL_SECONDS*2));
|
||||||
|
Thread thread1 = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("lock1");
|
||||||
|
RLock lock = rwlock.readLock();
|
||||||
|
Assert.assertTrue(lock.tryLock());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
thread1.start();
|
||||||
|
thread1.join();
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConcurrency_SingleInstance() throws InterruptedException {
|
||||||
|
final AtomicInteger lockedCounter = new AtomicInteger();
|
||||||
|
|
||||||
|
final Random r = new SecureRandom();
|
||||||
|
int iterations = 15;
|
||||||
|
testSingleInstanceConcurrency(iterations, new RedissonRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run(RedissonClient redisson) {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("testConcurrency_SingleInstance");
|
||||||
|
RLock lock;
|
||||||
|
if (r.nextBoolean()) {
|
||||||
|
lock = rwlock.writeLock();
|
||||||
|
} else {
|
||||||
|
lock = rwlock.readLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
lockedCounter.incrementAndGet();
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.assertEquals(iterations, lockedCounter.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConcurrencyLoop_MultiInstance() throws InterruptedException {
|
||||||
|
final int iterations = 100;
|
||||||
|
final AtomicInteger lockedCounter = new AtomicInteger();
|
||||||
|
|
||||||
|
final Random r = new SecureRandom();
|
||||||
|
testMultiInstanceConcurrency(16, new RedissonRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run(RedissonClient redisson) {
|
||||||
|
for (int i = 0; i < iterations; i++) {
|
||||||
|
boolean useWriteLock = r.nextBoolean();
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("testConcurrency_MultiInstance1");
|
||||||
|
RLock lock;
|
||||||
|
if (useWriteLock) {
|
||||||
|
lock = rwlock.writeLock();
|
||||||
|
} else {
|
||||||
|
lock = rwlock.readLock();
|
||||||
|
}
|
||||||
|
lock.lock();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(10);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
lockedCounter.incrementAndGet();
|
||||||
|
|
||||||
|
rwlock = redisson.getReadWriteLock("testConcurrency_MultiInstance1");
|
||||||
|
if (useWriteLock) {
|
||||||
|
lock = rwlock.writeLock();
|
||||||
|
} else {
|
||||||
|
lock = rwlock.readLock();
|
||||||
|
}
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.assertEquals(16 * iterations, lockedCounter.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConcurrency_MultiInstance() throws InterruptedException {
|
||||||
|
int iterations = 100;
|
||||||
|
final AtomicInteger lockedCounter = new AtomicInteger();
|
||||||
|
|
||||||
|
final Random r = new SecureRandom();
|
||||||
|
testMultiInstanceConcurrency(iterations, new RedissonRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run(RedissonClient redisson) {
|
||||||
|
RReadWriteLock rwlock = redisson.getReadWriteLock("testConcurrency_MultiInstance2");
|
||||||
|
RLock lock;
|
||||||
|
if (r.nextBoolean()) {
|
||||||
|
lock = rwlock.writeLock();
|
||||||
|
} else {
|
||||||
|
lock = rwlock.readLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
lockedCounter.incrementAndGet();
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.assertEquals(iterations, lockedCounter.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue