【问题标题】:Regarding running threads in parallel and return after关于并行运行线程并在之后返回
【发布时间】:2014-02-17 00:10:48
【问题描述】:

下面是我编写的一个类,其目的是我们从主程序创建不同的线程,这些线程并行运行,并且在所有线程完成执行后主线程恢复执行。代码中的 t.join 将下一个线程连接到第一个线程。假设如果有 2 个线程使用随机数生成器生成 8 和 9 作为整数,那么主线程会在 17 秒后恢复。目的是并行创建线程,以便主线程在第 9 秒后恢复(第一个线程在前 8 秒内完全运行,然后第二个线程在接下来的 1 秒内完成执行)。是否可以通过更改以下代码来创建这样的代码?

我通过使用一个静态变量来解决它,该变量在执行后由每个线程递增,当线程数达到某个阈值时,我们停止执行。但是有没有其他方法可以做到这一点?

import java.util.Random;


public class ThreadsPlay {

public static void main(String[] args) {

    try
    {
        for(int i=3;i<12;i=i+3)
        {
            Thread t=new Thread(){

                Random r=new Random();
                int count=r.nextInt(10);

                public void run()
                {
                    try
                    {
                        System.out.println("Thread+count="+count);
                        Thread.sleep(count*1000);

                    }
                    catch(Exception e)
                    {
                        e.printStackTrace();
                    }

                }

            };
            t.start();
            t.join();
        }


    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

}

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    保留您已启动的线程列表,并且在它们全部启动之前不要加入:

    List<Thread> threads = new ArrayList<Thread>();
    
    for(int i=3;i<12;i=i+3)
    {
        Thread t=new Thread()
        {
            Random r=new Random();
            int count=r.nextInt(10);
    
            public void run()
            {
                try
                {
                    System.out.println("Thread+count="+count);
                    Thread.sleep(count*1000);
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
        };
        t.start();
        threads.add(t);
    }
    
    // now wait for all threads to finish
    for (Thread t : threads) {
        t.join();
    }
    

    为了解释差异,我将介绍您提到的主要方法使用count = 8count = 9 启动两个线程的情况。

    加入第一个 for 循环(您的代码) - 17 秒:

    • main方法启动并输入for
    • main 用count=8 启动第一个线程
    • main 调用 join 并在线程工作时阻塞 8 秒
    • 第一个线程结束,main 重新进入for 并以count=9 启动第二个线程
    • main 调用 join 并在线程工作时阻塞 9 秒
    • 第二个线程完成,主线程完成

    加入第二个 for 循环 - 9 秒:

    • main方法启动,先进入for
    • main 用count=8 启动第一个线程
    • main 重新进入第一个for 并以count=9 启动第二个线程
    • 第一个for 完成后,两个线程关闭并运行
    • main 进入第二个for 并在第一个线程上调用join
    • 主要阻塞 8 秒,而 两个 线程都工作
    • 第一个线程结束,main 重新进入第二个 for 并在第二个线程上调用 join
    • main 阻塞 1 秒,因为 9 秒线程一直在工作
    • 第二个线程完成,主线程完成

    现在你可能会说,如果第一个线程有count=9 而第二个线程有count=8 会发生什么?加入第二个 for 循环时,顺序无关紧要,始终为 9 秒

    • main 进入第二个for 并在第一个线程上调用join
    • 主阻塞 9 秒,而 两个 线程都工作
    • 第二个线程完成,而 main 正在等待第一个线程完成
    • 第一个线程结束,main 重新进入第二个 for 并在第二个线程上调用 join
    • main 阻塞 0 秒,因为第二个线程一直在工作并且在 8 秒后已经完成
    • 主要饰面

    【讨论】:

    • 你能解释一下for循环中发生了什么吗?
    • 我刚刚更新了我的答案,让我知道是否可以解决问题
    猜你喜欢
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-18
    • 2011-08-16
    相关资源
    最近更新 更多