Source:
<code>public void testRequestResponseHandlerThreadExitFlow() throws Exception { Properties props = getNonBlockingRouterProperties("DC1"); VerifiableProperties verifiableProperties = new VerifiableProperties((props)); MockClusterMap mockClusterMap = new MockClusterMap(); MockTime mockTime = new MockTime(); router = new NonBlockingRouter(new RouterConfig(verifiableProperties), new NonBlockingRouterMetrics(mockClusterMap), new MockNetworkClientFactory(verifiableProperties, mockSelectorState, MAX_PORTS_PLAIN_TEXT, MAX_PORTS_SSL, CHECKOUT_TIMEOUT_MS, new MockServerLayout(mockClusterMap), mockTime), new LoggingNotificationSystem(), mockClusterMap, mockTime); assertExpectedThreadCounts(1); setOperationParams(); mockSelectorState.set(MockSelectorState.ThrowExceptionOnAllPoll); FutureResult<String> futureResult = (FutureResult<String>) router.putBlob(putBlobProperties, putUserMetadata, putChannel); try { while (!futureResult.isDone()) { mockTime.sleep(1000); Thread.yield(); } String blobId = futureResult.get(); Assert.fail("The operation should have failed"); } catch (ExecutionException e) { Assert.assertEquals("Should have received Operation timeout exception", RouterErrorCode.OperationTimedOut, ((RouterException) e.getCause()).getErrorCode()); } setOperationParams(); mockSelectorState.set(MockSelectorState.ThrowThrowableOnSend); futureResult = (FutureResult<String>) router.putBlob(putBlobProperties, putUserMetadata, putChannel); while (TestUtils.numThreadsByThisName("RequestResponseHandlerThread") > 0) { <START> Thread.yield(); <END> } try { futureResult.get(); Assert.fail("The operation should have failed"); } catch (ExecutionException e) { Assert.assertEquals("Should have received Operation timeout exception", RouterErrorCode.RouterClosed, ((RouterException) e.getCause()).getErrorCode()); } assertClosed(); Assert.assertEquals("No ChunkFiller Thread should be running after the router is closed", 0, TestUtils.numThreadsByThisName("ChunkFillerThread")); Assert.assertEquals("No RequestResponseHandler should be running after the router is closed", 0, TestUtils.numThreadsByThisName("RequestResponseHandlerThread")); Assert.assertEquals("All operations should have completed", 0, router.getOperationsCount()); }</code><technical_language>a do this join() get a handle thread</technical_language>

Target:
public void testRequestResponseHandlerThreadExitFlow() throws Exception { Properties props = getNonBlockingRouterProperties("DC1"); VerifiableProperties verifiableProperties = new VerifiableProperties((props)); MockClusterMap mockClusterMap = new MockClusterMap(); MockTime mockTime = new MockTime(); router = new NonBlockingRouter(new RouterConfig(verifiableProperties), new NonBlockingRouterMetrics(mockClusterMap), new MockNetworkClientFactory(verifiableProperties, mockSelectorState, MAX_PORTS_PLAIN_TEXT, MAX_PORTS_SSL, CHECKOUT_TIMEOUT_MS, new MockServerLayout(mockClusterMap), mockTime), new LoggingNotificationSystem(), mockClusterMap, mockTime); assertExpectedThreadCounts(1); setOperationParams(); mockSelectorState.set(MockSelectorState.ThrowExceptionOnAllPoll); Future future = router.putBlob(putBlobProperties, putUserMetadata, putChannel); try { while (!future.isDone()) { mockTime.sleep(1000); Thread.yield(); } future.get(); Assert.fail("The operation should have failed"); } catch (ExecutionException e) { Assert.assertEquals(RouterErrorCode.OperationTimedOut, ((RouterException) e.getCause()).getErrorCode()); } setOperationParams(); mockSelectorState.set(MockSelectorState.ThrowThrowableOnSend); future = router.putBlob(putBlobProperties, putUserMetadata, putChannel); TestUtils.getThreadByThisName("RequestResponseHandlerThread").join(); try { future.get(); Assert.fail("The operation should have failed"); } catch (ExecutionException e) { Assert.assertEquals(RouterErrorCode.RouterClosed, ((RouterException) e.getCause()).getErrorCode()); } assertClosed(); Assert.assertEquals("No ChunkFiller Thread should be running after the router is closed", 0, TestUtils.numThreadsByThisName("ChunkFillerThread")); Assert.assertEquals("No RequestResponseHandler should be running after the router is closed", 0, TestUtils.numThreadsByThisName("RequestResponseHandlerThread")); Assert.assertEquals("All operations should have completed", 0, router.getOperationsCount()); }