|
|
1
29
|
|
|
2
55
Java中的多线程有两种基本方式。使用这些方法创建的每个逻辑任务都应该在需要和可用时在新的核心上运行。 方法一: 定义一个可运行的或线程对象(它可以在构造函数中获得可运行的),并用thread.start()方法启动它。它将在操作系统提供的任何核心上执行——通常是负载较低的核心。 辅导的: Defining and Starting Threads 方法二: 定义实现可运行(如果不返回值)或可调用(如果返回值)接口的对象,其中包含处理代码。将这些任务从java.util.concurrent包传递给executorService。java.util.concurrent.executors类有许多方法来创建标准的、有用的executorservices类型。 Link 执行者教程。 根据个人经验,执行器的固定和缓存线程池非常好,尽管您希望调整线程计数。run time.getRuntime().availableProcessors()可在运行时用于计算可用核心。当应用程序完成后,您需要关闭线程池,否则应用程序将不会退出,因为线程池线程仍在运行。 获得好的多核性能有时是很棘手的,并且充满了gotchas:
另一个问题是:控制工作很难!一个好的实践是拥有一个创建和提交任务的管理器线程,然后拥有两个带有工作队列的工作线程(使用ExecutorService)。 我只想谈谈这里的关键点——多线程编程被许多专家认为是最难的编程主题之一。它是不直观的,复杂的,抽象性通常很弱。 edit——使用ExecutorService的示例:
|
|
|
3
17
首先,你应该向自己证明你的程序可以运行 更快 在多个核心上。许多操作系统努力在同一个核心上运行程序线程。 如果可能的话 . 在同一个内核上运行有许多优点。CPU缓存是热的,这意味着该程序的数据被加载到CPU中。锁定/监视/同步对象位于CPU缓存中,这意味着其他CPU不需要跨总线执行缓存同步操作(代价高昂!). 有一件事很容易让你的程序一直在同一个CPU上运行,那就是过度使用锁和共享内存。你的线程不应该互相通信。线程在同一内存中使用相同对象的频率越低,它们在不同CPU上运行的频率就越高。它们使用相同内存的频率越高,就越需要阻塞等待另一个线程。 每当操作系统看到另一个线程的一个线程块时,它将尽可能在同一个CPU上运行该线程。它减少了在CPU间总线上移动的内存量。我想这就是你在程序中看到的结果。 |
|
4
8
首先,我建议你阅读 "Concurrency in Practice" by Brian Goetz .
这是迄今为止描述并发Java编程的最好的书。 并发性是“容易学习,难掌握”。我建议在尝试之前多读一些关于这个主题的文章。很容易让多线程程序在99.9%的时间内正常工作,并且失败0.1%。不过,以下是一些让您开始学习的提示: 有两种常见的方法可以使程序使用多个核心:
在最底层,一个人可以 create and destroy threads . Java使得以可移植的跨平台方式创建线程变得很容易。 因为它往往会花费昂贵的时间来创建和销毁线程,Java现在包括 Executors 创建可重用的线程池。任务可以分配给执行者,结果可以通过未来的对象来检索。 通常情况下,一个人有一个任务可以分为较小的任务,但最终的结果需要放在一起。例如,使用合并排序,可以将列表分成越来越小的部分,直到每个核心都进行排序。但是,由于每个子列表都是经过排序的,所以需要合并才能得到最终排序的列表。由于这是“分而治之”的问题相当普遍,因此 JSR framework 它可以处理底层的分布和连接。这个框架很可能包含在Java 7中。 |
|
|
5
4
在Java中没有设置CPU亲和力的方法。 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4234402 如果必须这样做,请使用JNI创建本机线程并设置它们的关联性。 |
|
6
1
你应该以一种 许多 将callable交给ExecutorService并使用invokeAll(…)执行。 然后,您可以在运行时从Executors类中选择合适的实现。一个建议是调用executors.newFixedThreadPool(),其数字大致与CPU核心的数量相对应,以保持忙碌。 |
|
|
7
1
最简单的方法是将程序分解为多个进程。操作系统将在核心之间分配它们。 更难的是将程序分解为多个线程,并信任JVM来正确地分配它们。这通常是人们利用可用硬件所做的。 编辑 多处理程序如何“更容易”?这是一个正在进行的步骤。
管道中的每个步骤都是类似的结构。包括任何处理的9行开销。 这可能不是最有效的。但这很容易。 并发进程的总体结构不是一个JVM问题。这是一个操作系统问题,所以使用shell。
唯一剩下的就是为管道中的数据对象进行一些序列化。
标准序列化工作正常。读
http://java.sun.com/developer/technicalArticles/Programming/serialization/
有关如何序列化的提示。您可以替换
|
|
|
8
1
我认为这个问题与Java并行处理框架(JPPF)有关。使用它,您可以在不同的处理器上运行不同的作业。 |
|
|
9
1
前面在 Why does this Java code not utilize all CPU cores? . 请注意,这只适用于JVM,因此您的应用程序必须已经在使用线程(在这一点上或多或少是“正确的”): http://ch.sun.com/sunnews/events/2009/apr/adworkshop/pdf/5-1-Java-Performance.pdf |
|
|
10
1
您可以使用下面的API Executors 用Java 8版本
由于工作窃取机制的存在,空闲线程会从繁忙线程的任务队列中窃取任务,从而增加总吞吐量。
从
grepcode
,实施
|