15

每次我必须创建可变数量的线程。我通过创建一个线程数组并创建多个线程来做到这一点。

但是,我不明白如何启动这 n 个线程,其行为类似于多线程概念。我希望它们并行运行。

请指导如果在这个场景中做什么。

4

5 回答 5

38

但是,我不明白如何启动这 n 个线程,其行为类似于多线程概念。我希望它们并行运行。

您当然可以使用循环创建线程数组:

 Thread[] threads = new Thread[NUM_JOBS_TO_CREATE];
 for (int i = 0; i < threads.length; i++) {
     threads[i] = new Thread(new Runnable() {
         public void run() {
             // some code to run in parallel
             // this could also be another class that implements Runnable
         }
     });
     threads[i].start();
 }

这将导致线程在后台并行运行。然后,您可以稍后加入他们,等待他们全部完成后再继续。

// wait for the threads running in the background to finish
for (Thread thread : threads) {
    thread.join();
}

但我建议不要自己管理线程,而是使用内置的JavaExecutors。他们做这一切是因为你更容易管理。这种方法的好处之一是它将任务与运行它们的线程分开。例如,您可以启动 10 个线程来并行运行 1000 个和 1000 个任务。

这是一些示例ExecutorService代码:

 // create a pool of threads, 10 max jobs will execute in parallel
 ExecutorService threadPool = Executors.newFixedThreadPool(10);
 // submit jobs to be executing by the pool
 for (int i = 0; i < NUM_JOBS_TO_CREATE; i++) {
    threadPool.submit(new Runnable() {
         public void run() {
             // some code to run in parallel
             // this could also be another class that implements Runnable
         }
     });
 }
 // once you've submitted your last job to the service it should be shut down
 threadPool.shutdown();
 // wait for the threads to finish if necessary
 threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);

有关详细信息,请参阅有关线程执行器的 Java 教程

于 2012-04-10T16:06:57.437 回答
3

尽量不要创建线程数组并尝试管理它们——它很快就会变成一个令人震惊的混乱。如果你需要一个线程池来运行任务,你需要一个生产者-消费者队列。创建一个并在创建线程时将其(或包含它作为成员的线程池对象实例)传递给线程。线程循环,获取任务并执行它们。

执行此操作的简单方法是使用@Gray (+1) 详述的 ExecutorService。

为了强调,我再说一遍,不要试图对数组、列表或向量中的线程进行微观管理、启动它们、在“老板/管理”循环中检查它们的状态、终止/中止它们、销毁它们等等。它是就像保时捷 911 - 在花费大量金钱/时间来获得一辆之后,你会得到一些似乎可以正常工作的东西,然后它会突然破碎并将你旋转成一棵树。

为长时间阻塞的作业使用专用线程,为那些可以集中快速完成的作业使用线程池。

于 2012-04-10T16:33:21.163 回答
2

基本伪代码:

create x threads, store them in an array or list;
for each thread in the list/array
   call start() on the thread object;
于 2012-04-10T16:05:54.223 回答
2

在一个需要多线程的类中,我在类的顶部设置:

private static final ExecutorService executor = Executors.newCachedThreadPool();

& 在 Java 8+ 中,只要我需要在新线程中运行一些东西,就使用 lamda 表达式:

executor.submit(() -> {
        myOtherClass.myFunction(doSomething);
});

使用newCachedThreadPoolJava 将根据系统上的 cpu 核心数管理线程总数,并在一段时间不活动后自动停止它们(60默认为秒)。

于 2018-01-08T11:05:48.163 回答
0
Scanner reader = new Scanner(System.in);
    System.out.println("Enter a positive number: ");
    int n = reader.nextInt();
    if(n>0){
        Thread[] ob = new Thread[n];
        for (int i = 0; i < ob.length; i++) {
            int num = i+1;
            ob[i] = new Thread(new Runnable() {
         public void run() {
             System.out.println("Hello, I am Thread #"+num);
         }
            });
            ob[i].start();
        }
    }else{
        System.out.println("Please Enter A Positive Integer");
    }
于 2019-03-09T14:56:20.590 回答