奇怪的 Hazelcat IMap#put() 行为
我的基于 Hazelcast 的程序可以在两种模式下工作:提交者和 worker。
提交者通过一些键将一些POJO放入分布式地图,例如:hazelcastInstance.getMap(MAP_NAME).put(key, value);
Worker 有一个无限循环(内部为超时),它必须从 map 处理实体。现在,我只是在此循环中打印地图大小。Thread.sleep(1000L);
这就是问题所在。我启动工人应用程序。然后,我同时启动四个提交者(每个提交者向地图添加一个条目并终止其工作)。但是,在所有提交者应用完成后,辅助应用会打印任意大小:有时它检测到只添加了一个条目,有时是两个,有时是三个(实际上它从未见过所有四个条目)。
这个简单的流程有什么问题?我在Hazelcast文档中读到过该方法是同步的,因此它保证在返回后,条目被放置在分布式映射中并被复制。但在我的实验中似乎并非如此。put()
UPD(代码)
提交者:
public void submit(String key) {
Object mySerializableObject = ...
IMap<String, Object> map = hazelcastInstance.getMap(MAP_NAME);
map.putIfAbsent(key, mySerializableObject, TASK_TTL_IN_HOURS, TimeUnit.HOURS);
}
工人:
public void process() {
while (true) {
IMap<String, Object> map = hazelcastInstance.getMap(MAP_NAME);
System.out.println(map.size());
// Optional<Map.Entry<String, Object>> objectToProcess = getObjectToProcess();
// objectToProcess.ifPresent(objectToProcess-> processObject(id, objectToProcess));
try {
Thread.sleep(PAUSE);
} catch (InterruptedException e) {
LOGGER.error(e.getMessage(), e);
}
}
}
我注释掉了“处理”部分本身,因为现在我只是想获得地图的一致状态。上面的代码每次打印不同的结果,例如:“4, 3, 1, 1, 1, 1, 1, 1...”(所以它甚至可以暂时看到4个提交的任务,但随后他们...消失)。
UPD(日志)
工人:
...
tasksMap.size() = 0
tasksMap.size() = 0
tasksMap.size() = 0
tasksMap.size() = 0
tasksMap.size() = 1
tasksMap.size() = 2
tasksMap.size() = 2
tasksMap.size() = 2
tasksMap.size() = 2
tasksMap.size() = 2
...
提交者 1:
Before: tasksMap.size() = 0
After: tasksMap.size() = 1
提交者 2:
Before: tasksMap.size() = 1
After: tasksMap.size() = 4
提交者3:
Before: tasksMap.size() = 1
After: tasksMap.size() = 2
提交者 4:
Before: tasksMap.size() = 3
After: tasksMap.size() = 4