【问题标题】:Is multithreading faster than single thread?多线程比单线程快吗?
【发布时间】:2016-08-09 15:37:31
【问题描述】:

我想检查多线程是否比单线程快,然后我在这里做一个演示:

public class ThreadSpeedTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("cpu number:"
                + Runtime.getRuntime().availableProcessors());
        singleThreadStart();
//      secondThreadStart();
//      fiveThreadStart();
    }

    private static void sum() {
        long sum = 0;
        for (int i = 0; i < 1000000; i++) {
            sum += i;
        }
        System.out.println(sum);
    }

    private static void singleThreadStart() {
        new Thread(new Runnable() {

            public void run() {
                long start = System.nanoTime();
    //          sum();
    //          sum();
    //          sum();
                sum();
                sum();
                long end = System.nanoTime();
                System.out.println("cost time:" + (end - start));
            }
        }).start();
    }

    private static void secondThreadStart() {
        long start = System.nanoTime();
        Thread thread1 = new Thread(new Runnable() {

            public void run() {
                sum();
            }
        });
        thread1.start();
        Thread thread2 = new Thread(new Runnable() {

            public void run() {
                sum();
            }
        });
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        long end = System.nanoTime();
        System.out.println("cost time:" + (end - start));
    }

    private static void fiveThreadStart() {
        long start = System.nanoTime();
        Thread thread1 = new Thread(new Runnable() {

            public void run() {
                sum();
            }
        });
        thread1.start();
        Thread thread2 = new Thread(new Runnable() {

            public void run() {
                sum();
            }
        });
        thread2.start();
        Thread thread3 = new Thread(new Runnable() {

            public void run() {
                sum();
            }
        });
        thread3.start();
        Thread thread4 = new Thread(new Runnable() {

            public void run() {
                sum();
            }
        });
        thread4.start();
        Thread thread5 = new Thread(new Runnable() {

            public void run() {
                sum();
            }
        });
        thread5.start();

        try {
            thread1.join();
            thread2.join();
            thread3.join();
            thread4.join();
            thread5.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        long end = System.nanoTime();
        System.out.println("cost time:" + (end - start));
    }
}

首先我用两个 sum 方法运行 singleThreadStart,结果是

cpu number:4
499999500000
499999500000
cost time:6719000

然后我运行secondThreadStart,结果是

cpu number:4
499999500000
499999500000
cost time:14299000

然后我用五个sum方法运行singleThreadStart,结果是

cpu number:4
499999500000
499999500000
499999500000
499999500000
499999500000
cost time:10416000

最后我运行了fiveThreadStart,结果是

cpu number:4
499999500000
499999500000
499999500000
499999500000
499999500000
cost time:15708000

我的问题是:

  1. SecondThreadStart 比 singleThreadStart 花费更多时间,是不是因为创建线程的成本?
  2. cpu 数为 4,尽管创建线程有成本,那么使用超过 4 个线程会比使用 4 个线程慢吗?
  3. 如果我想做一些需要更多时间的事情,用四个线程来做最好吗?

【问题讨论】:

  • 使用 theads 会产生开销,并且您还应该看到Amdahl's law
  • 3.如果我想做一些花费很多时间的事情,最好用四个线程来做? - 请详细说明

标签: java multithreading processor


【解决方案1】:

1.SecondThreadStart比singleThreadStart耗时,是不是因为创建线程的开销?

创建线程肯定有开销。

2.cpu个数是4,尽管创建线程有成本,所以使用线程数大于4会比使用四个线程慢?

如果线程很快完成(不受 IO 限制和 CPU 限制),即使线程数多于 CPU 内核数,您也可以获得良好的结果。

3.如果我想做一些耗时的事情,最好用四个线程来做?

您可以使用高级 java 并发类(newWorkStealingPool of Executors

参考这个 SE 问题:

Java's Fork/Join vs ExecutorService - when to use which?

一般:

多线程可以通过使用更多的 CPU 能力来提高应用程序的吞吐量。

这取决于很多因素。

  1. 线程数
  2. CPU 内核
  3. 线程创建成本和上下文切换(可能对多线程起作用)
  4. 数据结构
  5. 数据的可变性(可能对多线程起作用)
  6. 数据结构的共享访问/并发(可能适用于多线程)
  7. 应用程序类型:CPU 绑定或 IO 绑定

如果您的应用程序是多线程将提供出色的结果

  1. 更少的 CPU 绑定,更少的 IO 绑定(但这些应用程序仍然可以使用多线程)

  2. 没有共享数据

如果不是,则性能取决于上述因素,并且单线程应用程序和多线程应用程序之间的吞吐量会有所不同。

一些很好的 SE 问题:

https://softwareengineering.stackexchange.com/questions/97615/what-can-multiple-threads-do-that-a-single-thread-cannot

Does multithreading always yield better performance than single threading?

Why single thread is faster than multithreading in Java?

好文章:

thetechsolo.wordpress.com文章

java-performance文章

【讨论】:

  • 只是想在这里挑战“非 IO 绑定”部分。在许多情况下,多线程为 I/O 绑定应用程序提供了出色的结果,因为您可以并行执行多项操作,而不是阻塞整个应用程序等待单个 I/O 操作。当使用比 cpu 内核更多的线程是有益的时,这也是最常见的情况。在某些情况下,您可以在单线程应用程序中解决它(类似选择的行为),但在 java 中,很多 API 是阻塞的(例如 JDBC)。
  • 我想强调一个事实,IO 绑定的应用程序性能取决于磁盘 IO
【解决方案2】:
  1. 创建额外的线程绝对是有代价的。在启动新线程之前,您应该需要做大量的工作。
  2. 我认为这意味着您有一个四核 CPU。线程的最佳数量实际上取决于工作负载,如果线程出于任何原因等待它们可能能够上下文切换到另一个线程,并且您可能会看到线程数量大于物理内核数量的好处。
  3. 我不明白这个问题。

【讨论】:

  • 3.一旦所有 CPU 都忙起来,添加更多线程可能会增加 CPU 密集型任务的开销。 +1