/** * Measure the estimated active thread count in the current thread group. * Since this calls {@link Thread.activeCount} it should be called from the * main thread or one started by the main thread. Threads included in the * count can be in any state. * For a more accurate count we could use {@link Thread.getAllStackTraces().size()} * but that freezes the JVM and incurs a high overhead. * @return An estimated thread count, good for showing the thread count * over time. */ public static int getActiveThreadCount() { return Thread.activeCount(); }
/** * @param threadId Thread ID. * @return Thread name if found. */ public static String threadName(long threadId) { Thread[] threads = new Thread[Thread.activeCount()]; int cnt = Thread.enumerate(threads); for (int i = 0; i < cnt; i++) if (threads[i].getId() == threadId) return threads[i].getName(); return "<failed to find active thread " + threadId + '>'; }
/** dump thread stacks if pool does not terminate promptly. */ private void checkThreadTermination() { try { if (!threadPool.awaitTermination(1, TimeUnit.SECONDS)) { int activeCount = Thread.activeCount(); System.err.println("Thread pool not terminated in time; printing stack traces..."); Thread[] threads = new Thread[activeCount + 2]; int count = Thread.enumerate(threads); for (int i = 0; i < count; i++) { System.err.println("Thread: " + threads[i].getName()); Thread.dumpStack(); } } } catch (InterruptedException e) { e.printStackTrace(); } }
public static JSONObject getSystemConfig(Runtime runtime) throws Exception { JSONObject system = new JSONObject(); String xmx = DAO.getConfig("Xmx", ""); system.put("assigned_memory", runtime.maxMemory()); system.put("used_memory", runtime.totalMemory() - runtime.freeMemory()); system.put("available_memory", runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory()); system.put("cores", runtime.availableProcessors()); system.put("threads", Thread.activeCount()); system.put("runtime", System.currentTimeMillis() - Caretaker.startupTime); system.put("time_to_restart", Caretaker.upgradeTime - System.currentTimeMillis()); system.put("load_system_average", OS.getSystemLoadAverage()); Double systemCpuLoad = OS.getSystemCpuLoad(); system.put("load_system_cpu", systemCpuLoad.isNaN() || systemCpuLoad.isInfinite() ? 0 : systemCpuLoad.doubleValue()); system.put("load_process_cpu", systemCpuLoad.isNaN() || systemCpuLoad.isInfinite() ? 0 : systemCpuLoad); system.put("server_threads", LoklakServer.getServerThreads()); system.put("server_uri", LoklakServer.getServerURI()); system.put("Xmx", xmx); return system; }
@Signature public static Memory getActiveCount(Environment env, Memory... args){ return LongMemory.valueOf(Thread.activeCount()); }
public static Collection<String> interestingValues() { final List<String> strings = new ArrayList<String>(); if (withIp() == false) { strings.add("Machine: " + getHostName()); } strings.add("PLANTUML_LIMIT_SIZE: " + GraphvizUtils.getenvImageLimit()); strings.add("Processors: " + Runtime.getRuntime().availableProcessors()); final long freeMemory = Runtime.getRuntime().freeMemory(); final long maxMemory = Runtime.getRuntime().maxMemory(); final long totalMemory = Runtime.getRuntime().totalMemory(); final long usedMemory = totalMemory - freeMemory; final int threadActiveCount = Thread.activeCount(); strings.add("Max Memory: " + format(maxMemory)); strings.add("Total Memory: " + format(totalMemory)); strings.add("Free Memory: " + format(freeMemory)); strings.add("Used Memory: " + format(usedMemory)); strings.add("Thread Active Count: " + threadActiveCount); return Collections.unmodifiableCollection(strings); }
private static Thread[] getThreads() { int count = Thread.activeCount() + 1; for (; ; ) { Thread[] threads = new Thread[count]; int filled = Thread.enumerate(threads); if (filled < threads.length) { return Arrays.copyOf(threads, filled); } count *= 2; } }
@Test public void constructor_does_not_start_a_new_Thread() throws IOException { int activeCount = Thread.activeCount(); newCeServer(); assertThat(Thread.activeCount()).isSameAs(activeCount); }
@SuppressWarnings("deprecation") public void sleepServer(final int seconds, final CountDownLatch l) throws InterruptedException, IOException { Thread[] allthreads = new Thread[Thread.activeCount()]; Thread.enumerate(allthreads); for (final Thread t : allthreads) { if (t.getName().contains("SyncThread:0")) { Thread sleeper = new Thread() { public void run() { try { t.suspend(); l.countDown(); Thread.sleep(seconds * 1000); t.resume(); } catch (Exception e) { LOG.error("Error suspending thread", e); } } }; sleeper.start(); return; } } throw new IOException("ZooKeeper thread not found"); }
@Test public void start_starts_a_new_Thread() throws IOException { int activeCount = Thread.activeCount(); newCeServer().start(); assertThat(Thread.activeCount()).isSameAs(activeCount + 1); }
@Test public void testHeartbeatThreadClose() throws Exception { ConsumerCoordinator coordinator = prepareCoordinatorForCloseTest(true, true, true); coordinator.ensureActiveGroup(); time.sleep(heartbeatIntervalMs + 100); Thread.yield(); // Give heartbeat thread a chance to attempt heartbeat closeVerifyTimeout(coordinator, Long.MAX_VALUE, requestTimeoutMs, requestTimeoutMs); Thread[] threads = new Thread[Thread.activeCount()]; int threadCount = Thread.enumerate(threads); for (int i = 0; i < threadCount; i++) assertFalse("Heartbeat thread active after close", threads[i].getName().contains(groupId)); }
@Test public void testCustomRequestTaskThreadName() { String expectedName = "topicProcessorRequestTaskCreate"; //NOTE: the below single executor should not be used usually as requestTask assumes it immediately gets executed ExecutorService customTaskExecutor = Executors.newSingleThreadExecutor(r -> new Thread(r, expectedName)); TopicProcessor<Object> processor = TopicProcessor.builder() .executor(Executors.newCachedThreadPool()) .requestTaskExecutor(customTaskExecutor) .bufferSize(8) .waitStrategy(WaitStrategy.liteBlocking()) .autoCancel(true) .build(); processor.requestTask(Operators.cancelledSubscription()); Thread[] threads = new Thread[Thread.activeCount()]; Thread.enumerate(threads); //cleanup to avoid visibility in other tests customTaskExecutor.shutdownNow(); processor.forceShutdown(); Condition<Thread> customRequestTaskThread = new Condition<>( thread -> thread != null && expectedName.equals(thread.getName()), "a thread named \"%s\"", expectedName); Assertions.assertThat(threads) .haveExactly(1, customRequestTaskThread); }
@Test public void testDefaultRequestTaskThreadName() { String mainName = "topicProcessorRequestTask"; String expectedName = mainName + "[request-task]"; TopicProcessor<Object> processor = TopicProcessor.builder().name(mainName).bufferSize(8).build(); processor.requestTask(Operators.cancelledSubscription()); Thread[] threads = new Thread[Thread.activeCount()]; Thread.enumerate(threads); //cleanup to avoid visibility in other tests processor.forceShutdown(); Condition<Thread> defaultRequestTaskThread = new Condition<>( thread -> thread != null && expectedName.equals(thread.getName()), "a thread named \"%s\"", expectedName); Assertions.assertThat(threads) .haveExactly(1, defaultRequestTaskThread); }
@Test public void testDefaultRequestTaskThreadName() { String mainName = "workQueueProcessorRequestTask"; String expectedName = mainName + "[request-task]"; WorkQueueProcessor<Object> processor = WorkQueueProcessor.builder().name(mainName).bufferSize(8).build(); processor.requestTask(Operators.cancelledSubscription()); Thread[] threads = new Thread[Thread.activeCount()]; Thread.enumerate(threads); //cleanup to avoid visibility in other tests processor.forceShutdown(); Condition<Thread> defaultRequestTaskThread = new Condition<>( thread -> thread != null && expectedName.equals(thread.getName()), "a thread named \"%s\"", expectedName); Assertions.assertThat(threads) .haveExactly(1, defaultRequestTaskThread); }
@Test public void testCustomRequestTaskThreadShare() { String expectedName = "topicProcessorRequestTaskShare"; //NOTE: the below single executor should not be used usually as requestTask assumes it immediately gets executed ExecutorService customTaskExecutor = Executors.newSingleThreadExecutor(r -> new Thread(r, expectedName)); TopicProcessor<Object> processor = TopicProcessor.builder().share(true) .executor(Executors.newCachedThreadPool()) .requestTaskExecutor(customTaskExecutor) .bufferSize(8) .waitStrategy(WaitStrategy.liteBlocking()) .autoCancel(true) .build(); processor.requestTask(Operators.cancelledSubscription()); Thread[] threads = new Thread[Thread.activeCount()]; Thread.enumerate(threads); //cleanup to avoid visibility in other tests customTaskExecutor.shutdownNow(); processor.forceShutdown(); Condition<Thread> customRequestTaskThread = new Condition<>( thread -> thread != null && expectedName.equals(thread.getName()), "a thread named \"%s\"", expectedName); Assertions.assertThat(threads) .haveExactly(1, customRequestTaskThread); }
@Test public void testCustomRequestTaskThreadNameCreate() { String expectedName = "workQueueProcessorRequestTaskCreate"; //NOTE: the below single executor should not be used usually as requestTask assumes it immediately gets executed ExecutorService customTaskExecutor = Executors.newSingleThreadExecutor(r -> new Thread(r, expectedName)); WorkQueueProcessor<Object> processor = WorkQueueProcessor.builder() .executor(Executors.newCachedThreadPool()) .requestTaskExecutor(customTaskExecutor) .bufferSize(8) .waitStrategy(WaitStrategy.liteBlocking()) .autoCancel(true) .build(); processor.requestTask(Operators.cancelledSubscription()); processor.subscribe(); Thread[] threads = new Thread[Thread.activeCount()]; Thread.enumerate(threads); //cleanup to avoid visibility in other tests customTaskExecutor.shutdownNow(); processor.forceShutdown(); Condition<Thread> customRequestTaskThread = new Condition<>( thread -> thread != null && expectedName.equals(thread.getName()), "a thread named \"%s\"", expectedName); Assertions.assertThat(threads) .haveExactly(1, customRequestTaskThread); }
@Test(timeout = 15000L) public void cancelDoesNotHang() throws Exception { WorkQueueProcessor<String> wq = WorkQueueProcessor.create(); Disposable d = wq.subscribe(); Assert.assertTrue(wq.downstreamCount() == 1); d.dispose(); while (wq.downstreamCount() != 0 && Thread.activeCount() > 2) { } }
@Test(timeout = 15000L) public void completeDoesNotHang() throws Exception { WorkQueueProcessor<String> wq = WorkQueueProcessor.create(); wq.subscribe(); Assert.assertTrue(wq.downstreamCount() == 1); wq.onComplete(); while (wq.downstreamCount() != 0 && Thread.activeCount() > 2) { } }
@Test() public void retryNoThreadLeak() throws Exception { WorkQueueProcessor<Integer> wq = WorkQueueProcessor.<Integer>builder().autoCancel(false).build(); wq.handle((integer, sink) -> sink.error(new RuntimeException())) .retry(10) .subscribe(); wq.onNext(1); wq.onNext(2); wq.onNext(3); wq.onComplete(); while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) { } }
@Test(timeout = 15000L) public void disposeSubscribeNoThreadLeak() throws Exception { WorkQueueProcessor<String> wq = WorkQueueProcessor.<String>builder().autoCancel(false).build(); Disposable d = wq.subscribe(); d.dispose(); d = wq.subscribe(); d.dispose(); d = wq.subscribe(); d.dispose(); while (wq.downstreamCount() != 0 && Thread.activeCount() > 2) { } }