具有四核处理器的笔记本电脑中的Javamultithreading

我正在阅读Java教程,其中提到在具有单个处理器的机器中不会发生实际的multithreading。 它提到操作系统为Java进程分配了一段指定的时间,而JVM线程调度程序会在一段时间内一次运行一个线程来获取线程。

我有一台四核处理器的笔记本电脑 – 通过在每个核心运行一个线程,可以以编程方式更快地运行multithreading程序吗? 我问这个问题的原因是因为书中提到只有真正的多处理器系统才能同时做多件事。

即使是单个CPU也可以在宽松的意义上同时执行“多个事物”,但它们并非真正并行。 您可以启动100个线程在单个核心上运行,并且它们将获得时间片,在此期间每个线程可以运行一些指令,从而产生它们都在同一时间执行的印象。

正如我在另一篇SOpost中所说: 双核机器上的multithreading?

术语线程通常包含三个抽象层:

  1. 用户线程是应用程序启动的线程,并将N:M映射到:
  2. 内核线程是由操作系统管理的线程 ,将N:M映射到:
  3. 硬件线程 ,它们是可用的实际物理资源。

Java线程是用户线程。 CPU中的4个核心计为硬件线程。 由于跨层的映射是N:M,您可以看到可以将多个用户线程映射到较少数量的硬件线程。

现在,说了这个,通常有两类线程活动,每个都有自己的怪癖:

  1. I / O线程 :这些线程大部分时间都在等待来自流的读/写操作,并在此期间被阻塞(它们不会被调度执行,直到事件发生才唤醒它们)。 CPU上有亮点,即使在单核上也可以同时运行。
  2. 计算线程 :这些线程执行大量数字运算并最大限度地使用CPU。 通常启动超过(可用内核数量的2倍)这样的线程会降低性能,因为CPU具有有限数量的function单元:ALU,FPU等。

上面的第二类线程让您可以在四核CPU上真正看到好处或运行multithreadingJava程序。 下面是一个程序的简单示例,该程序首先按顺序执行1.000.000.000个数字的平方,然后使用具有4个线程的线程池并行执行:

import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; class ThreadTask implements Runnable { private int total = 0; public ThreadTask(int total) { this.total = total; } @Override public void run() { int value = 0; for(int i = 0; i < total; i++) { value = i * i; } } } public class Test { public static void main(String[] args) throws InterruptedException { int total = 1000000000; long start = System.currentTimeMillis(); long value = 0; for(int i = 0; i < total; i++) { value = i * i; } long stop = System.currentTimeMillis(); System.out.println((stop - start) + " ms"); ExecutorService exec = Executors.newFixedThreadPool(4); start = System.currentTimeMillis(); for(int i = 0; i < 4; i++) { exec.submit(new ThreadTask(total / 4)); } exec.shutdown(); exec.awaitTermination(10, TimeUnit.SECONDS); stop = System.currentTimeMillis(); System.out.println((stop - start) + " ms"); } } 

如果运行速度太快,请随意调整总值。 现在我正在使用英特尔凌动的上网本,所以它不是很快。

多核处理器可以“真正”并行化应用程序中的工作,最多可达到您拥有的核心数。 在你的情况下,那将是4个线程。 阅读Wikipedia上有关多核与多处理器的更多信息。 话虽如此,您可以在单核CPU上通过multithreading算法实现性能优势,尽管您只有一个处理器。

使用多核处理器所带来的性能提升在很大程度上取决于所使用的软件算法及其实现。 特别是,可能的增益受到可以并行化以同时在多个内核上运行的软件部分的限制; Amdahl定律描述了这种效应。 在最好的情况下,所谓的令人尴尬的并行问题可能会在核心数量附近实现加速因子,如果问题分裂得足以适应每个核心的缓存,则可能会更多,从而避免使用更慢的主系统内存。 然而,大多数应用程序都没有加速,除非程序员投入大量精力来重新分解整个问题2 。 软件的并行化是一个重要的研究课题。

另请参阅此StackOverflow问题。

即使只有一个处理器,多个线程也可以使您的程序更快,这一切都取决于您尝试加速的工作。 例如,如果您的线程正在等待IO。 如果它纯粹是计算机,那么你可能想要将线程限制为核心数。

测量它用实验测试它。

我可以确认,在我的i3笔记本电脑上,并行运行的算法的速度几乎是串行算法的两倍。

下面添加更多上下文…

这些是高度计算的算法,没有I / O. 基本上,计算N个大型arrays的统计数据,其中每个arrays可以独立完成。 我发现使用2-4个线程的线程池都会产生大约相同的速度增加 – 2倍。 转到8个或更multithreading,当你获得更多争用(并且正在消耗更多内存)时,事情开始稍微放缓。 在具有更多内核的处理器上,这些值会发生变化。