@Test public void worksInMultithreadedEnvironment() throws InterruptedException { var executorService = new ThreadPoolExecutor( 3, 5, 10000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>() ); var integers = ConcurrentHashMap.<Integer>newKeySet(); int repeatCount = 25000; final var countDownLatch = new CountDownLatch(repeatCount); for (int i = 0; i < repeatCount; i++) { executorService.submit(() -> { integers.add(sequentialMessageIdGenerator.nextId()); countDownLatch.countDown(); }); } if (!countDownLatch.await(2000, TimeUnit.MILLISECONDS)) { fail("Timeout"); } assertEquals(repeatCount + 1, sequentialMessageIdGenerator.nextId()); assertEquals(repeatCount, integers.size()); executorService.shutdown(); }
@Override public int nextId() { return atomicInteger.incrementAndGet(); }
SequentialMessageIdGenerator implements MessageIdGenerator { @Override public int nextId() { return atomicInteger.incrementAndGet(); } }
SequentialMessageIdGenerator implements MessageIdGenerator { @Override public int nextId() { return atomicInteger.incrementAndGet(); }  }
SequentialMessageIdGenerator implements MessageIdGenerator { @Override public int nextId() { return atomicInteger.incrementAndGet(); }  @Override int nextId(); }
SequentialMessageIdGenerator implements MessageIdGenerator { @Override public int nextId() { return atomicInteger.incrementAndGet(); }  @Override int nextId();  }