我是使用Hazelcast的新手。我在我的Web应用程序中使用Hazelcast 3.6-EA作为数据存储。应用程序将在多个实例上运行,因此当多个线程尝试使用相同的Map时,我需要实现锁定机制以避免race conditions。
欲望行为将遵循:开始使用Map的第一个问题应该锁定它并执行所需的更新。另一个insance应该看到Map被锁定并跳过执行任何更新。
因此,这种锁定的主要好处应该是避免两次执行相同的代码。
public void consumePerformances(Date date) {
Collection<Integer> performancesId = timeformPerformanceService.getPerformancesIds();
timeFormService.getPerformancesByMeetingDate(date, new DataCallback<List<Performance>>() {
@Override
public void onResponse(List<Performance> performances) {
Map<Integer, Performance> newPerformancesMap =
performances.stream().collect(Collectors.toMap(Performance::getPerformanceId, Function.identity()));
newPerformancesMap.entrySet().stream().filter(element -> performancesId.contains(element.getKey()))
.forEach(element -> element.getValue().setUpdateDate(date));
timeformPerformanceService.save(newPerformancesMap.values());
}
@Override
public void onError(Throwable throwable) {
}
});
}
public void save(Collection<Performance> performances) {
LOGGER.info("Save performances to the hazelcast");
IMap<Integer, Performance> map = hazelcastInstance.getMap(PERFORMANCE_CACHE_NAME);
performances.forEach(item -> {
try {
if (map.tryLock(item.getPerformanceId(), 1, TimeUnit.SECONDS, 300, TimeUnit.SECONDS)) {
try {
map.put(item.getPerformanceId(), item);
} finally {
try {
map.unlock(item.getPerformanceId());
} catch (IllegalMonitorStateException e) {
LOGGER.error("Lock was released, due to lease time was expired");
}
}
} else {
LOGGER.info("Lock on key: {} is not released yet", map.get(item.getPerformanceId()));
}
} catch (InterruptedException e) {
LOGGER.error("Lock error. Key could not be equal to null");
}
}
);
}
如果我正确理解锁定机制并且上面实现的行为是否能给我预期的结果,我有疑问。
我会对任何细节解释表示感谢。
另外,请告诉我,如果线程锁定地图,另一个只执行get(key)
操作,会出现什么样的行为?