### Question:
ThreadId { public void unlockAndDestroy() { if (this.destroyed) { return; } this.destroyed = true; if (!this.lock.isHeldByCurrentThread()) { LOG.warn("Fail to unlockAndDestroy with {}, the lock is held by {} and current thread is {}.", this.data, this.lock.getOwner(), Thread.currentThread()); return; } this.lock.unlock(); } ThreadId(final Object data, final OnError onError); Object getData(); Object lock(); void unlock(); void join(); @Override String toString(); void unlockAndDestroy(); void setError(final int errorCode);  }### Answer:
@Test public void testUnlockAndDestroy() throws Exception { AtomicInteger lockSuccess = new AtomicInteger(0); CountDownLatch latch = new CountDownLatch(10); this.id.lock(); for (int i = 0; i < 10; i++) { new Thread() { @Override public void run() { if (ThreadIdTest.this.id.lock() != null) { lockSuccess.incrementAndGet(); } latch.countDown(); } }.start(); } this.id.unlockAndDestroy(); latch.await(); assertEquals(0, lockSuccess.get()); assertNull(this.id.lock()); }