【问题标题】:unable to predict when all the threads have finished execution无法预测所有线程何时完成执行
【发布时间】:2016-08-09 06:03:14
【问题描述】:

这是我的代码

package pe.entel.ftp;

public class Myclass implements Runnable {
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
    public static void main(String[] args) {
        Myclass runnable = new Myclass();
        ThreadGroup tg1 = new ThreadGroup("Parent ThreadGroup");

        for (int i = 0; i < 100; i++) {
            Thread t1 = new Thread(tg1, runnable, i + "");
            t1.start();
            System.out.println("Thread Group Name: " + tg1.getName());

        }
        while (tg1.isDestroyed()) {
            System.out.println("yes success");
        }

        System.out.println("completed");

    }
}

而我的 o/p 部分是

  Thread Group Name: Parent ThreadGroup
  Thread Group Name: Parent ThreadGroup
  Thread Group Name: Parent ThreadGroup
  Thread Group Name: Parent ThreadGroup
  Thread Group Name: Parent ThreadGroup
 completed
 84 
 86
 88
 90
 92
 94
 96
 98
 95
 97
 99

这里我无法准确预测线程组何时完成执行。甚至,用于检查线程组是否被破坏的while循环也不起作用。即使在打印完成后,一些线程仍在执行。

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    线程组未完成执行。如果要等待所有线程完成,则必须收集它们并等待所有线程:

    List<Thread> allThreads = new ArrayList<>();
    
    for (int i = 0; i < 100; i++) {
      Thread t1 = new Thread(tg1, runnable, i + "");
            t1.start();
       allThreads.add(t1);  
    }
    
    allThreads.forEach(Thread::join);
    

    ThreadGroups 存在的时间比它们包含的线程长,您可能希望在到目前为止的所有线程都完成后将新线程添加到 ThreadGroup。它们只是对线程进行分组,而不是控制它们。

    【讨论】:

    • 我想一次执行所有线程。对于你给出的代码。线程会因为join而一个接一个地执行。
    • 没有。线程在 for 循环中使用t1.start()command 启动并并行运行。顺序完成的是连接,即线程末端的等待。您等待第一个线程以join() 结束。发生这种情况时,您将等待第二个线程完成。如果这比第一个线程快,join() 会立即返回,然后你会跳到等待第三个线程,依此类推。
    【解决方案2】:

    我无法准确预测线程组何时完成执行

    另一种方法是使用ExecutorService 线程池,而不是自己分叉线程:

    ExecutorService threadPool = Executors.newCachedThreadPool();
    for (int i = 0; i < 100; i++) {
        threadPool.submit(new Myclass());
    }
    // shutdown the pool after the last runnable has been submitted
    threadPool.shutdown();
    // wait for all of the jobs to finish
    threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
    

    您也可以使用Executors.newFixedThreadPool(#) 只 fork 一定数量的线程来限制并发操作的数量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-25
      • 2022-01-10
      • 2015-03-25
      • 1970-01-01
      • 2017-01-24
      • 1970-01-01
      相关资源
      最近更新 更多