2012-01-30 22 views
6

我正在浏览一个Java教程,其中提到实际的多线程不会在具有单个处理器的机器中发生。它提到操作系统为Java进程分配一段指定的时间,并且JVM线程调度程序在一小段时间内一次运行一个线程。四核处理器的笔记本电脑中的Java多线程

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

+1

继续发展并为此添加了多线程标签 - 它不仅仅是一个以Java为中心的问题。希望你会得到一些很好的答案。 – Makoto 2012-01-30 05:39:17

+0

您阅读的文章可能是来自多核处理器之前的时间,因此只有多处理器计算机才能使用它。 – Hurda 2012-01-30 09:56:19

回答

7

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

正如我在另一个岗位SO曾经说过:multithreading on dual core machine?

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

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

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

,话虽如此,一般有两类主题活动,每一个都有自己的怪癖:

  1. I/O线程:这些线程花费大量的时间在等待读/写来自某个流的操作并在此期间被阻止(它们不会被计划执行,直到发生事件才会唤醒它们)。 CPU上有灯光,即使在单个内核上也可以同时运行。
  2. 计算线程:这些线程会执行大量的数字运算并最大限度地使用CPU。由于CPU的功能单元数量有限:ALU,FPU等,所以通常启动多于(可用内核的数量的两倍),这样的线程将降低性能。

上面的第二类线程让您真的看到了好处,或者在四核CPU上运行了多线程Java程序。这里是一个程序,执行使用一个线程池4个线程平方1.000.000.000数第一顺序和然后并行的一个简单的例子:

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

随意,如果它的运行速度过快,调整的total值。现在我正在与英特尔凌动处理上网本,因此速度并不快。

+0

感谢都铎王朝 - 将试试:) – 2012-01-31 18:41:38

1

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

测量它用实验进行测试。

2

多核处理器可以“真正”地将应用程序中的工作并行化至核心数量。在你的情况下,这将是4个线程。有关多核处理器与多处理器的更多信息,请致电Wikipedia。尽管如此,尽管您只有一个处理器,但您可以在单核CPU上使用多线程算法实现性能优势。

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

另请参阅此StackOverflow问题。

1

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

更上下文中添加...

这些是没有I/O高度计算算法。基本上,计算N个大数组的统计量,每个数组可以独立完成。我发现使用2-4个线程的线程池产生大约相同的速度提高 - 2倍。去8个或更多的线程,事情开始放缓,因为你得到更多的争用(并使用更多的内存)。在具有更多内核的处理器上,这些值将会改变。