如何检查那个池 'reuses' 线程

How to check that pool 'reuses' Thread

为了检查主题我写了代码:

public class ThreadPoolTest {
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 100; i++) {
            if (test() != 5 * 100) {
                throw new RuntimeException("main");
            }
        }
        test();
    }

    private static long test() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(100);
        CountDownLatch countDownLatch = new CountDownLatch(100 * 5);
        Set<Thread> threads = Collections.synchronizedSet(new HashSet<>());
        AtomicLong atomicLong = new AtomicLong();
        for (int i = 0; i < 5 * 100; i++) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        threads.add(Thread.currentThread());
                        atomicLong.incrementAndGet();
                        countDownLatch.countDown();
                    } catch (Exception e) {
                        System.out.println(e);
                    }


                }
            });
        }
        executorService.shutdown();
        countDownLatch.await();
        if (threads.size() != 100) {
            throw new RuntimeException("test");
        }
        return atomicLong.get();
    }
}

如你所见,我使用 HashSet<Thread>

只有线程不可变时,它的用法才是正确的。至少在测试中。

据我了解,equals/hashCode 未被覆盖,因此继承自 Object。

因此,如果我的测试不正确,请回答错误的地方。
如果你知道更聪明的方法,请分享这个。

正如我在评论中提到的,我认为您的代码实际上设法验证了 test() 创建了 100 个线程并使用它们执行了 500 个小任务。如果不是这种情况,您的 RuntimeException 断言肯定会触发。

验证这一点的另一种方法是使用 ThreadLocal 来计算线程的实际数量 运行。

我创建了以下单元测试,它使用 ThreadLocal 来计算 Executor 创建的线程数。尝试研究其输出以确信创建的线程数。

@Test
public void threadCounter() throws Throwable {
    ThreadLocal<Integer> number = new ThreadLocal<Integer>() {
        private final AtomicInteger values = new AtomicInteger();

        @Override
        protected Integer initialValue() {
            return values.getAndIncrement();
        }
    };

    ExecutorService threadPool = Executors.newFixedThreadPool(100);

    for (int i = 0 ; i < 500 ; i++) {
        final int count = i;
        threadPool.submit(() -> System.out.printf("%-4s : %-20s - %s\n", count, Thread.currentThread().getName(), number.get()));
    }

    threadPool.shutdown();
    threadPool.awaitTermination(10, TimeUnit.SECONDS);

    Assert.assertEquals(100, number.get().intValue());

}

I am not sure that I undestand correct how thread [pool] 'reuses' threads.

池线程(a.k.a., 工作线程)有一个run()方法,就像任何其他线程一样,这就是"re-use" 发生。基本上,工作线程的 run() 方法从队列中选择 tasks(即 client-supplied Runnable 对象),并运行它们:

class ReallySimplePoolWorker {

    public ReallySimplePoolWorker(BlockingQueue<Runnable> workQueue) {
        this->workQueue = workQueue;
    }

    public void Run( ) {
        while (...not shutting down...) {
            Runnable task = workQueue.take();
            try {
                task.run();
            } catch (Exception ex) {
                ...notify the pool object of the exception...
            }
        }
    }

    private final BlockingQueue<Runnable> workQueue;
}