2010-01-07 83 views
9

我正在写一个优化算法,创建大约100个线程。目前,我一次启动它们(for-loop),然后告诉每个线程它应该加入()。Java约100个并行线程,内存管理

我的问题是,现在每个线程使用多少内存,所以堆空间异常不会花费很长时间。我想要某种调度,但不知道如何实现它。

我有这样的想法:开始10个线程,每次完成其中一个完成一个新的。因此,一次只能运行10个线程,直到没有线程离开。

有人有想法或知道如何实现这样的事情吗?

非常感谢和问候来自科隆

马尔科

+3

如果您对java和并发感兴趣,我强烈推荐这本书:http://www.javaconcurrencyinpractice.com/ – 2010-01-07 10:53:24

回答

1

考虑您将要使用的机器中的内核数量。如果您通常运行的线程数等于核心数,性能将最好。正如KLE所说,使用线程池。

+0

我目前运行2,因为它是来自Intel的Core2Duo。性能看起来不错...... – Marco 2010-01-08 09:52:18

+4

如果你完全受CPU限制,这可能是真的,但如果有任何阻塞操作(例如,IO,睡眠,某些类型的锁定),那么你通常需要比内核更多的线程来保持核心充分利用。 – mikera 2011-01-20 02:30:19

2

而是开始一个新的线程来完成新任务的,你有了更好的:

  • 具有的任务队列来执行(而不是线程来运行)
  • 使用较小线程池(如迈克尔提到的)来处理这些任务

速度和内存的差异是巨大的,因为您不必为每个任务启动和停止线程。

java.util.concurrent包解释了一切。 一本书会更容易阅读,虽然:-(

4

下面是一个例子,让你开始首先,你需要导入:

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

然后你需要把里面的东西方法:

ExecutorService pool = Executors.newFixedThreadPool(10); 
    for(final Task task: tasks) { 
     pool.execute(new Runnable() { 
      @Override 
      public void run() { 
       task.execute(); 
      } 
     }); 
    } 
    pool.shutdown(); 
    while(!pool.awaitTermination(1, TimeUnit.SECONDS)) { 
     System.out.println("Waiting for tasks to shutdown"); 
    } 

有关上述的一些注意事项:

  • 你需要实现自己的01真正实现Task类 你的算法
  • 任务类不只是 有一个执行方法(事实上,如果 它有签名,你可以只 让你的任务是实现Runnable 和避免匿名内部类)
  • 您需要确保 您使用的所有内容都正确 已同步。 java.util.concurrent.atomic中的课程为 相当不错,前提是您需要更新共享状态 (例如,如果您希望 拥有您已处理多少个任务 的计数器)。
  • 您通常只需要尽可能多的 线程执行,因为您的机器上有核心 /cpus。经常 性能经常上升,当 线程数量下降。 通常情况下,如果 您的任务花费了大量时间 阻止,您只能使用更多的线程。