java - 线程在 ThreadPoolExecutor 中等待

标签 java threadpool

这段代码运行速度非常慢。我转储了线程,几乎有一个线程同时运行,但是当我将 ExecutorService 更改为 ForkJoinPool 时,代码运行得非常快。我不知道为什么线程在等待,我的电脑有 8 个核心...

enter image description here

public class Tests {

    public static void main(String[] args) throws InterruptedException {

        int NUM_OF_THREADS = 8;
        int NUM_OF_INCREMENTS = 100_000_000;
        //ExecutorService service = Executors.newWorkStealingPool();
        ExecutorService service = Executors.newFixedThreadPool(NUM_OF_THREADS);
        final Counter counter = new StupidCounter();

        long before = System.currentTimeMillis();
        for (int i = 0; i < NUM_OF_INCREMENTS; i++) {
            service.submit(newCounterClient(counter, i));
        }
        service.shutdown();
        service.awaitTermination(1, TimeUnit.MINUTES);
        long end = System.currentTimeMillis();
        System.out.println(end - before);
        System.out.println(counter.getCounter());
    }


    static class CounterClient implements Runnable {
        private Counter counter;
        private int num;

        public CounterClient(Counter counter, int num) {
            this.counter = counter;
            this.num = num;
        }

        @Override
        public void run() {
            counter.increment();
        }
    }

    static interface Counter {
        void increment();

        long getCounter();
    }

    static class StupidCounter implements Counter {
        long i = 0;

        @Override
        public void increment() {
            i++;
        }

        @Override
        public long getCounter() {
            return i;
        }
    }

}
<小时/>
"pool-1-thread-7" #17 prio=5 os_prio=31 tid=0x00007faaa481c000 nid=0x6503 waiting on condition [0x0000700001d6d000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000006c006b3d8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
    at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:439)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(617Thread.java:745)

最佳答案

很难从这段代码中得出任何真实结论,因为它实际上没有任何事情。执行器的内部队列是瓶颈,这就是为什么你一次只能看到 1 个线程“工作”。它并没有真正工作,它正在从队列中获取下一个任务,使所有其他线程(也正在获取下一个任务)等待。除了 LinkedBlockingQueue.take() 的功能之外,您并没有真正测试任何东西。 .

increment()方法不是线程安全的,因此基本上您正在测试错误的代码,并且结果几乎无关紧要。如果您输入CounterClient任务执行实际工作,这需要几毫秒,与ForkJoinPool相比,您会发现性能差异(如果有的话)要小得多。 .

关于java - 线程在 ThreadPoolExecutor 中等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41180302/

相关文章:

java - 继承以及在何处声明预期的通用对象

python - Python 中的 Flask 多进程工作池

c++ - 主线程和线程池

java - 从不同线程的多个任务中检索数据

java - 调试时 JSP 可用的变量在哪里?

java - for 循环中的 i++ &++i 有什么区别?

java - 为什么我在 Java 中收到 "missing return statement"错误,即使我在第二类中有 return 语句和线程主错误中的异常?

java - 如何在 quarkus 上设置 http 线程池最大大小

python - 为什么python多进程池比单进程慢?

java - Restful WebService 的问题