在java中运行多少个线程?

时间:2011-03-31 11:21:49

标签: java multithreading

我有这个绝妙的主意,可以加快生成36个文件所需的时间:使用36个线程!不幸的是,如果我用36个线程/会话启动一个连接(一个j2ssh连接对象),那么一切都比我一次执行每个线程要多得多。 现在,如果我尝试创建36个新连接(36个j2ssh连接对象),那么每个线程都有一个到服务器的单独连接,要么我的内存异常(不知何故程序仍然运行,并成功结束其工作,更慢比我一个接一个地执行一个线程的时间)。

那该怎么办?如何找到我应该使用的最佳线程数? 因为Thread.activeCount()在开始我的36个线程之前是3?我正在使用联想笔记本电脑英特尔酷睿i5。

9 个答案:

答案 0 :(得分:10)

您可以使用ExecutorService将其缩小到更合理的线程数。您可能希望使用接近可用处理器核心数量的东西,例如:

int threads = Runtime.getRuntime().availableProcessors();
ExecutorService service = Executors.newFixedThreadPool(threads);
for (int i = 0; i < 36; i++) {
    service.execute(new Runnable() {
        public void run() {
            // do what you need per file here
        }
    });
}
service.shutdown();

答案 1 :(得分:4)

一个好的做法是生成相当于处理器内核数量的线程。我通常使用Executors.fixedThreadPool(numOfCores)执行程序服务并继续从我的作业队列中提取作业,这很简单。 : - )

答案 2 :(得分:3)

您的Intel i5有两个内核;超线程使它们看起来像四个。因此,您只能获得四个内核的并行化;你的其余线程都是时间切片。

假设每个线程只有1MB RAM用于创建线程,然后添加每个线程处理文件所需的内存。这将让您了解为什么会出现内存错误。你正在处理的文件有多大?您可以看到,如果它们非常大,同时将它们存储在内存中,您就会遇到问题。

我假设接收文件的服务器可以接受多个连接,因此尝试这个有价值。

我用1个线程进行基准测试,然后增加它们,直到我发现性能曲线变平为止。

答案 3 :(得分:1)

暴力:逐渐增加轮廓。逐渐增加线程数并检查性能。由于连接数仅为36,因此应该很容易

答案 4 :(得分:1)

你需要明白,如果你创建了36个线程,你仍然有一个或两个处理器,并且大部分时间都会在威胁之间切换。

我会说你稍微增加线程,让我们说6并看到行为。然后从那里开始

答案 5 :(得分:1)

将线程数调整到机器大小的一种方法是使用

int processors = Runtime.getRuntime().availableProcessors();
int threads = processors * N; // N could 1, 2 or more depending on what you are doing.
ExecutorService es = Executors.newFixedThreadPool(threads);

答案 6 :(得分:1)

首先你必须找出瓶颈的位置

  • 如果是SSH连接,通常无法并行打开多个连接。如果需要,最好在一个连接上使用多个通道。

  • 如果是磁盘IO,创建多个线程写入(或读取)只会在访问不同磁盘时很有用(很少这样)。但是,当你在一个线程中等待磁盘IO时,你可以让另一个线程做CPU限制的事情。

  • 如果它是CPU,并且您有足够的空闲内核,则更多线程可以提供帮助。更重要的是,如果他们不需要访问公共数据。但是,比核心更多的线程(+一些做IO的线程)没有帮助。 (另请注意,您的服务器上通常还有其他进程。)

答案 7 :(得分:0)

使用比计算机核心数量更多的线程只会减慢整个过程的速度。它会加速,直到你达到这个数字。

答案 8 :(得分:0)

确保您没有创建比处理单元更多的线程,或者您可能会在上下文切换时创建比并发更多的开销。另外请记住,你只有1个硬盘和1个硬盘控制器,我怀疑多线程会在这里帮助你。