简体   繁体   中英

How to check that pool 'reuses' Thread

To check the subject I have wrote the code:

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();
    }
}

As you can see I use HashSet<Thread>

Its usage will be correct only if Thread immutable. at least within test.

As I understand equals/hashCode is not overriden and thus inherit from Object.

Thus, please answer if my test incorrect and where is mistake.
If you know more clever way, please share this.

As mentioned in my comment, I would argue that your code actually manages to verify that test() creates 100 threads and executes 500 small tasks using them. Your RuntimeException assertions would definitely fire if that was not the case.

Another approach to verifying this is to use a ThreadLocal to count the actual number of threads running.

I've created the following unit test which uses a ThreadLocal to count the number of threads created by the Executor . Try studying its output to be convinced of the number of threads created.

@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 pool thread (aka, worker thread ) has a run() method, just like any other thread, and that's where the "re-use" happens. Basically, the worker thread's run() method picks tasks (ie, the client-supplied Runnable objects) from a queue, and it runs them:

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM