【问题标题】:Creating dynamic number of threads concurrently同时创建动态线程数
【发布时间】:2012-04-22 22:48:08
【问题描述】:

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

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

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

【问题讨论】:

    标签: java multithreading parallel-processing


    【解决方案1】:

    但是,我不明白如何启动这 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();
    }
    

    但我建议不要自己管理线程,而是使用内置的Java Executors。他们做这一切是因为你更容易管理。这种方法的好处之一是它将 tasks 与运行它们的 threads 分开。例如,您可以启动 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 tutorial on the thread executors

    【讨论】:

    • 如果我有 1000 个作业,它将创建 1000 个对象,这会导致性能问题
    • 1000 个对象非常便宜@ManojRamanan。从对象带宽的角度来看,1000 个字符串更昂贵。如果您创建了一百万个对象,您可能会注意到一些 GC 问题,因此我们通常在队列上设置边界,以防Runnable 生产者比消费者快得多。
    • 感谢@Gray 提供的信息。您能否分享一些我目前正在使用此实现的信息。您如何测试它
    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      基本伪代码:

      create x threads, store them in an array or list;
      for each thread in the list/array
         call start() on the thread object;
      

      【讨论】:

      • 如果我这样做,线程不会并行运行。但是,它们作为普通函数调用按顺序运行
      • @sowmya 我认为您需要阅读线程。在一堆线程上按顺序调用 start() 并不意味着它们是按顺序运行的,它只是意味着它们是按顺序启动的。
      • 但是,它们是按照我启动它们的顺序依次执行的。据我所知,至少输出应该改变。但是,它没有发生。如果我错了,请纠正我。
      • 它们各自执行各自版本的函数。
      【解决方案4】:

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

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

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

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

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

      【讨论】:

        【解决方案5】:
        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");
            }
        

        【讨论】:

        • 欢迎来到 Stack Overflow。虽然这很可能是解决 OP 问题的代码,但请对代码的作用以及它回答问题的原因添加一些解释。
        猜你喜欢
        • 2012-06-25
        • 1970-01-01
        • 1970-01-01
        • 2012-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-11
        • 2011-05-31
        相关资源
        最近更新 更多