代码之家  ›  专栏  ›  技术社区  ›  Ermintar

Hazelcast锁不提供同步

  •  2
  • Ermintar  · 技术社区  · 6 年前

    我尝试在Hazelcast中实现方法同步,但它似乎在单个集群上都不起作用。

    我正在使用一个简单的hazelcast配置

    @Configuration
    public class HazelcastConfig {
        @Bean
        HazelcastInstance hazelcastInstance(){
            return Hazelcast.newHazelcastInstance();
        }
    }
    

    有一个示例服务,它使用时间戳生成一些ID。它应该是独一无二的,所以我用的是哈泽尔卡斯特提供的锁

    @Service
    public class MyService {
        @Autowired
        private HazelcastInstance hazelcastInstance;
    
        public Long generateVersion(){
            ILock lock = hazelcastInstance.getLock("version_key");
            try{
                lock.lock();
                return System.currentTimeMillis();
            } catch (Exception ex) {
                LOGGER.error("Could not generate version ", ex);
                throw ex;
            } finally{
                lock.unlock();
            }
        }
    }
    

    测试检查是否没有生成重复项。

    @Test
    public void test() throws InterruptedException, ExecutionException {
        List<Long> versions = new ArrayList();
        Collection<Callable<Long>> tasks = new ArrayList<>();
        int nThreads = 100;
        for(int i=0; i<nThreads; i++){
            tasks.add(new Callable<Long>() {
                @Override
                public Long call() throws Exception {
                    return myService.generateVersion();
                }
            });
        }
        ExecutorService executor = Executors.newFixedThreadPool(nThreads);
        List<Future<Long>> results = executor.invokeAll(tasks);
        for(Future<Long> result : results){
            Long pingResult = result.get();
            if (!versions.contains(pingResult))
                versions.add(pingResult);
            else
                throw new AssertionError("Found duplicate "+ pingResult);
        }
    }
    

    但是,在运行测试时,我得到了很多副本。测试在单个节点上运行(我计划稍后在集群环境上运行它)。

    Hazelcast是否在单个集群节点上提供同步?或者我配置错误了?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Neil Stevenson    6 年前

    System.getTimestamp() 可能不是唯一的。您可以调用它两次,得到相同的结果。

    你可以让Hazelcast为你生成ID https://docs.hazelcast.org//docs/3.10.5/javadoc/com/hazelcast/flakeidgen/FlakeIdGenerator.html