- Hazelcast 教程
- Hazelcast - 首页
- Hazelcast - 简介
- Hazelcast - 设置
- Hazelcast - 第一个应用程序
- Hazelcast - 配置
- 设置多节点实例
- Hazelcast - 数据结构
- Hazelcast - 客户端
- Hazelcast - 序列化
- Hazelcast 高级
- Hazelcast - Spring 集成
- Hazelcast - 监控
- Map Reduce 和聚合
- Hazelcast - 集合监听器
- 常见陷阱和性能提示
- Hazelcast 有用资源
- Hazelcast - 快速指南
- Hazelcast - 有用资源
- Hazelcast - 讨论
Hazelcast - ILock
java.util.concurrent.locks.Lock 提供了一个接口,可以在多线程环境中工作时实现并用于锁定关键部分,在 JVM 中。
类似地,ILock 扩展了接口以提供 Java Lock 的分布式版本。它提供类似的功能:lock、unlock、tryLock
但是 ILock 和 Java Lock 之间的一个主要区别在于,Java Lock 提供了对来自单个 JVM 中线程的关键部分的保护,而 ILock 提供了对单个 JVM 中线程以及多个 JVM 中线程的同步。
ILock 只有一个同步备份,这意味着如果我们有一个设置,例如,我们有 5 个 JVM 正在运行,则只有两个 JVM 将持有此变量。
让我们看一个有用函数的示例。
获取和释放锁
假设我们在两个 JVM 上执行以下代码。
示例
public static void main(String... args) throws IOException, InterruptedException {
//initialize hazelcast instance
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
// create a lock
ILock hzLock = hazelcast.getLock("lock_1");
IAtomicLong counter = hazelcast.getAtomicLong("counter");
// acquire lock
hzLock.lock();
System.out.println("Acquiring Lock");
try{
Thread.sleep(5000);
System.out.println("Incrementing Counter");
counter.incrementAndGet();
System.out.println("Counter: " + counter.get());
}
finally {
// release lock
System.out.println("Lock Released");
hzLock.unlock();
}
System.exit(0);
}
输出
上述函数的输出表明,第二个 JVM 只有在第一个 JVM 释放锁后才能获取锁。
Acquired Lock Incrementing Counter Counter: 1 Lock Released Acquired Lock Incrementing Counter Counter: 2 Lock Released
使用 tryLock 代替 Lock
为了减少死锁的可能性,建议使用 tryLock(timeout, unit) 方法而不是 lock()。默认情况下,lock() 的超时时间为 5 分钟,如果在该时间段内未获取锁,则会抛出 OperationTimeoutException 异常。tryLock 相反,根据在提供的时间段内是否获取锁返回布尔值。
示例
让我们在**两个 JVM**上执行以下代码。
public static void main(String... args) throws IOException, InterruptedException {
//initialize hazelcast instance
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
// create a lock
ILock hzLock = hazelcast.getLock("lock_1");
// acquire lock
if(hzLock.tryLock(2000, TimeUnit.SECONDS)) {
System.out.println("Acquired Lock");
Thread.sleep(5000);
System.out.println("Lock Released");
hzLock.unlock();
}
else
System.out.println("Couldn't acquire lock");
System.exit(0);
}
输出
代码的**输出**将是 -
Acquired Lock Couldn't acquire lock Lock Released
良好实践和诀窍
虽然获取锁非常有用,但建议将关键部分保持尽可能短。这确保了性能不会下降,并且还降低了死锁的可能性。
如果一个成员(已获取)出现故障,则锁会自动释放,其他成员可以争夺。
该锁是可重入的;它确保同一线程可以多次获取锁而不会导致死锁。
有用方法
| 序号 | 函数名称和描述 |
|---|---|
| 1 | lock() 获取提供的锁实例,以便任何其他线程都无法获取它。如果不可用,它会无限期地等待直到获取锁。 |
| 2 | unlock() 释放获取的锁 |
| 3 | tryLock(long time, TimeUnit unit) 尝试在给定的时间窗口内获取锁。如果获取了锁,则返回 true,否则返回 false。 |
| 4 | isLocked() 检查锁是否已被其他线程获取 |