如何创建用户定义的线程数?

时间:2012-01-08 18:30:36

标签: java multithreading

在我正在开发的程序中,我希望用户能够输入其处理器所具有的处理线程数,以便程序可以在线程数之间划分工作负载(它正在进行一般计算)用户的电脑有。

或者,是否有一种方法可以让程序检测系统配置以获取线程数而无需询问用户?这样会更好,但我不知道是否有办法做到这一点。

这是我唯一能想到的。我知道这是完全错误的,并且你不能用这种方式命名一个帖子,但我是初学者(仍在高中),我只想包含一些东西来表明我正在尝试。

for(int i = 0; i < threads; i++) {

    Thread thread(i) = new Thread(){
        public void run() {
            double endNum = 0;

            for(double numberRun = 0; numberRun <= calcs/threads; numberRun++){
                endNum += (num * 999999999);
            }

            System.out.println("Thread " + i + " complete! The numerical result of the calculation is " + endNum);
        }
    };
}

每个人都不确定我在说什么,我正在尝试创建计算机所拥有的线程数,即核心数,或者,如果它使用的是英特尔超线程,则是核心数量的两倍。您可以拥有比系统能够立即执行的更多线程,但我正在尝试做最有效的事情,并将计算总数除以系统能够同时执行的线程数。我不知道如何让用户定义线程数,然后创建该线程数(或让程序确定系统拥有的线程数,然后创建该数字)。

7 个答案:

答案 0 :(得分:4)

您可以通过以下方式了解JVM可以使用多少处理器

Runtime.getRuntime().availableProcessors()

用于拆分纯数值计算的线程的最佳数量可能是每个处理器一个。如果这些线程中的任何一个必须偶尔阻止IO,则可能更多。

答案 1 :(得分:3)

class Task implements Runnable {
  Task(/** Whatever you need to identify the subset of tasks to run goes here*/) {

  }

  public void run() {
    // do the calcs
  }
}

int nProcs = Runtime.getRuntime().getAvailableProcessors();

Task[] tasks = new Task[nProcs];
for (int i = 0; i < nProcs; i++) {
   tasks[i] = new Task(/** Whatever parameters for this batch*/);
   new Thread(tasks[i]).start(); 
   // Alternatively, use Executors.newFixedThreadPool() to get a service above, and submit the runnable there, getting a future for the result, something like this:
   Future f = executor.submit(task[i]);
}

}

答案 2 :(得分:2)

如果你要执行一堆不同的不同任务 - 而不是试图将一个大任务拆分成多个并行运行的小任务,你可能想要使用Executor

Executor e = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// run a single task
e.execute(new Runnable() {
    public void run() {
        // do stuff here
    }
});

正如其他人所指出的,线程池的最佳大小取决于各种因素,例如任务执行的IO数量,但可用内核的数量应该是合理的默认值。

答案 3 :(得分:1)

我喜欢用的是 ExecutorService executor = Executors.newFixedSizeThreadPool(int numberOfThreads);

然后让executor.execute(myRunnable)你的runnables :) 在这种方法中,您不负责创建线程,并且您可以保证不会创建不必要的线程。

但至于如何确定应该使用多少线程,由您来研究。

答案 4 :(得分:1)

在我看来,您正在寻找的也是线程任务的映射策略。例如,循环如:

for(int i = 0; i < LARGE_NUMBER; i++) {
    f(i);
}

可以转换为并行版本:

class Task implements Runnable {
    private int i;

    public Task(int i) {
       this.i = i;
    }       

    public void run() {
       f(i);
    }
}

然后用:

替换初始for循环
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < LARGE_NUMBER; i++) {
    exec.submit(new Task(i));
}

exec.awaitTermination(1000, TimeUnit.HOURS); // wait for all tasks to finish

ExecutorService将负责使用与可用处理器相关的多个线程以及回收线程,以便按需执行任务。

答案 5 :(得分:0)

线程的数量不依赖于处理器。如果您使用的是单处理器,那么您的程序将从一个线程跳转到另一个线程。

因此,您的方法中没有“不正确”(当然,如果您将正确使用它)。

答案 6 :(得分:0)

我想你问的是系统可以拥有的最大线程数?

正如here所讨论的那样,没有系统可以拥有的最大线程数(因为Java程序在Java虚拟机中运行,您将拥有的限制是Java虚拟机 - JVM的限制) 。限制取决于您可以分配给线程的资源量。

如果您询问当前正在运行多少个线程(可能是由任何外部程序或JVM内部启动的),那么您可能会发现它,但我认为它没有任何用处对于您的情况,因为您启动的线程与系统中运行的其他线程没有任何关系!

相关问题