### Question:
SequentialMessageIdGenerator implements MessageIdGenerator { @Override public int nextId() { return atomicInteger.incrementAndGet(); }  @Override int nextId();  }### Answer:
@Test public void startsFromOne() { var firstId = sequentialMessageIdGenerator.nextId(); assertEquals(1, firstId); }
@Test public void increasesByOne() { for (int i = 1; i < 100; i++) { assertEquals(i, sequentialMessageIdGenerator.nextId()); } }
@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(); }