线程池性能

4
我正在尝试理解使用线程池的优势,我编写了这段代码来查看使用固定线程池的时间改进。首先,我将线程池中的线程数设置为1,大约需要920毫秒,然后我将线程池中的线程数更改为2(和3,4,5,6,7...),需要1200毫秒,当线程同时运行时难道不应该更快吗?当我将其更改为缓存线程池时,也需要1200毫秒。
package threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Example3 {

public static void main(String[] args) {

    new Example3();

}

public Example3() {

    try {
        testFixedPool(1);
      //testFixedPool(2);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

public void testFixedPool(int numberOfThreads) throws InterruptedException {

    ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);

    long start = System.currentTimeMillis();

    executor.execute(new TaskPrintInteger(0, 10000));
    executor.execute(new TaskPrintInteger(1, 10000));
    executor.execute(new TaskPrintInteger(2, 10000));
    executor.execute(new TaskPrintInteger(3, 10000));
    executor.execute(new TaskPrintInteger(4, 10000));
    executor.execute(new TaskPrintInteger(5, 10000));
    executor.execute(new TaskPrintInteger(6, 10000));
    executor.execute(new TaskPrintInteger(7, 10000));
    executor.execute(new TaskPrintInteger(8, 10000));
    executor.execute(new TaskPrintInteger(9, 10000));
    executor.shutdown();

    while(!executor.isTerminated()){
    }

    System.out.println();
    System.out.println((System.currentTimeMillis()) - start);
}

private class TaskPrintInteger implements Runnable {

    private int number, times;

    public TaskPrintInteger(int number, int times) {

        this.number = number;
        this.times = times;
    }

    @Override
    public void run() {

        for (int i = 0; i < times; i++) {
            System.out.println(number);
        }

    }

}

}

7
不要只提交10个任务,尝试提交100,000个任务。同时,不要让它们输出到System.out,因为这会同步化(所以只有一个线程在打印,抵消了任何线程优势)。 - user253751
2
@immibis 这里的关键确实是 System.out.println() 调用的同步。并且并行处理不会提高任何 I/O 绑定的进程。 - biziclop
2个回答

7
您正在要求多个线程执行同一项活动,这很可能(虽然不保证)需要使用“同步”(synchronized):
System.out.println(number);

假设你有一个人,让她在一张纸上写“one”十次,每行一个单词。现在,你需要让同一个人再写十次“one”和十次“two”,每行一个单词,这样做哪个更快?
  1. 使用上面提到的那一个人。
  2. 请那个人带一个朋友来写“two”。规定他们从大厅的两端开始奔跑,谁先到纸条跑到哪儿就写哪个单词。然后他们跑回大厅尽头重复这个过程直到所有单词都被写下来。
我敢猜测第一个方案会更快。
如果有5个人都试图写下他们的单词10000遍呢?会混乱吧?没错!
如果你想要从线程中看到真正的改进,任务应该是完全隔离的,没有同步,特别是没有I/O!

1

当您拥有满足要求的资源时,最佳线程数可以为 1。向控制台编写内容是昂贵且单线程的操作,因此当您使用多个线程时,会增加开销而不是使程序更快。线程在独立运行时才能发挥最佳作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接