@Testpublic void sharedLock() throws Exception { // 创建共享锁
InterProcessLock lock = new InterProcessSemaphoreMutex(client, lockPath); // lock2 用于模拟其他客户端
InterProcessLock lock2 = new InterProcessSemaphoreMutex(client2, lockPath); // 获取锁对象
lock.acquire(); // 测试是否可以重入
// 超时获取锁对象(第一个参数为时间, 第二个参数为时间单位), 因为锁已经被获取, 所以返回 false
Assert.assertFalse(lock.acquire(2, TimeUnit.SECONDS)); // 释放锁
lock.release(); // lock2 尝试获取锁成功, 因为锁已经被释放
Assert.assertTrue(lock2.acquire(2, TimeUnit.SECONDS));
lock2.release();
}
public void sharedReentrantLock() throws Exception { // 创建可重入锁
InterProcessLock lock = new InterProcessMutex(client, lockPath); // lock2 用于模拟其他客户端
InterProcessLock lock2 = new InterProcessMutex(client2, lockPath); // lock 获取锁
lock.acquire(); try { // lock 第二次获取锁
lock.acquire(); try { // lock2 超时获取锁, 因为锁已经被 lock 客户端占用, 所以获取失败, 需要等 lock 释放
Assert.assertFalse(lock2.acquire(2, TimeUnit.SECONDS));
} finally {
lock.release();
}
} finally { // 重入锁获取与释放需要一一对应, 如果获取 2 次, 释放 1 次, 那么该锁依然是被占用, 如果将下面这行代码注释, 那么会发现下面的 lock2 获取锁失败
lock.release();
} // 在 lock 释放后, lock2 能够获取锁
Assert.assertTrue(lock2.acquire(2, TimeUnit.SECONDS));
lock2.release();
}
@Testpublic void sharedReentrantReadWriteLock() throws Exception { // 创建读写锁对象, Curator 以公平锁的方式进行实现
InterProce***eadWriteLock lock = new InterProce***eadWriteLock(client, lockPath); // lock2 用于模拟其他客户端
InterProce***eadWriteLock lock2 = new InterProce***eadWriteLock(client2, lockPath); // 使用 lock 模拟读操作
// 使用 lock2 模拟写操作
// 获取读锁(使用 InterProcessMutex 实现, 所以是可以重入的)
InterProcessLock readLock = lock.readLock(); // 获取写锁(使用 InterProcessMutex 实现, 所以是可以重入的)
InterProcessLock writeLock = lock2.writeLock(); /**
* 读写锁测试对象
*/
class ReadWriteLockTest { // 测试数据变更字段
private Integer testData = 0; private Set<Thread> threadSet = new HashSet<>(); // 写入数据
private void write() throws Exception {
writeLock.acquire(); try {
Thread.sleep(10);
testData++;
System.out.println("写入数据 \ t" + testData);
} finally {
writeLock.release();
}
} // 读取数据
private void read() throws Exception {
readLock.acquire(); try {
Thread.sleep(10);
System.out.println("读取数据 \ t" + testData);
} finally {
readLock.release();
}
} // 等待线程结束, 防止 test 方法调用完成后, 当前线程直接退出, 导致控制台无法输出信息
public void waitThread() throws InterruptedException { for (Thread thread : threadSet) {
thread.join();
}
} // 创建线程方法
private void createThread(int type) {
Thread thread = new Thread(new Runnable() { @Override
public void run() { try { if (type == 1) {
write();
} else {
read();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
threadSet.add(thread);
thread.start();
} // 测试方法
public void test() { for (int i = 0; i < 5; i++) {
createThread(1);
} for (int i = 0; i < 5; i++) {
createThread(2);
}
}
}
ReadWriteLockTest readWriteLockTest = new ReadWriteLockTest();
readWriteLockTest.test();
readWriteLockTest.waitThread();
}
测试结果如下:
写入数据 1
写入数据 2
读取数据 2
写入数据 3
读取数据 3
写入数据 4
读取数据 4
读取数据 4
写入数据 5
读取数据 5
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。