public void setError(final int errorCode) {
        if (this.destroyed) {
            LOG.warn("ThreadId: {} already destroyed, ignore error code: {}", this.data, errorCode);
            return;
        }
        this.lock.lock();
        try {
            if (this.destroyed) {
                LOG.warn("ThreadId: {} already destroyed, ignore error code: {}", this.data, errorCode);
                return;
            }
            if (this.onError != null) {
                this.onError.onError(this, this.data, errorCode);
            }
        } finally {
            // It may have been released during onError to avoid throwing an exception.
            if (this.lock.isHeldByCurrentThread()) {
                this.lock.unlock();
            }
        }
    }
@Test
    public void testSetError() throws Exception {
        this.id.setError(100);
        assertEquals(100, this.errorCode);
        CountDownLatch latch = new CountDownLatch(1);
        new Thread() {
            @Override
            public void run() {
                ThreadIdTest.this.id.setError(99);
                latch.countDown();
            }
        }.start();
        latch.await();
        assertEquals(99, this.errorCode);
    }