### Question:
CommonSelfIdGenerator { public synchronized long generateId() { long time = System.currentTimeMillis(); if (lastTime == time) { if (0L == (++sequence & SEQUENCE_MASK)) { time = waitUntilNextTime(time); } } else { sequence = 0; } lastTime = time; if (log.isDebugEnabled()) { log.debug("{}-{}-{}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(lastTime)), workerId, sequence); } return ((time - EPOCH) << TIMESTAMP_LEFT_SHIFT_BITS) | (workerId << WORKER_ID_LEFT_SHIFT_BITS) | sequence; }  void setWorkerId(final Long workerId); static long getWorkerIdLength(); synchronized long generateId(); static final long EPOCH; }### Answer:
@Test public void testThreadSafe() throws InterruptedException, ExecutionException { int nThread = 10; int idPerThread = 1000; CommonSelfIdGenerator commonSelfIdGenerator = new CommonSelfIdGenerator(); CountDownLatch countDownLatch = new CountDownLatch(nThread); Callable<List<Long>> generate = () -> { ArrayList<Long> ids = new ArrayList<>(); countDownLatch.countDown(); countDownLatch.await(); for (int i = 0; i < idPerThread; i++) { long l = commonSelfIdGenerator.generateId(); ids.add(l); } return ids; }; ExecutorService executorService = Executors.newFixedThreadPool(nThread); List<Future<List<Long>>> futureList = new ArrayList<>(); for (int i = 0; i < nThread; i++) { Future<List<Long>> futureResult = executorService.submit(generate); futureList.add(futureResult); } countDownLatch.await(); HashSet<Long> allIds = new HashSet<>(); for (Future<List<Long>> result : futureList) { List<Long> longs = result.get(); allIds.addAll(longs); } Assert.assertEquals(allIds.size(), nThread * idPerThread); }