加入工作方式不同

时间:2017-05-17 18:12:24

标签: java multithreading

在这里,我在java中学习线程,偶然发现了join()。现在, join(),应该让当前线程退出执行,然后下一个线程应该启动。但是,我得到了不同的输出。 我的代码是

 public class join extends Thread {
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                System.out.println(e);
            }
            System.out.println(i);
        }
    }
}

class bhago4 
{
    public static void main(String args[]) throws IOException 
{

        join j1 = new join();
        join j2 = new join();
        join j3 = new join();
        j3.start();
        j1.start();
        try {
            j1.join();

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

        }
        j2.start();
    }
}

我得到的输出是:

0
0
1
1
2
2
3
3
4
4
0
1
2
3
4

现在根据我的理解,当j3开始它应该打印0,然后它睡眠500ms,直到那时j1开始,它应该继续直到它结束,但这不会发生。两个线程的o / p是交替的。为什么会这样?

3 个答案:

答案 0 :(得分:1)

当你运行j3.start()j1.start()时,你创建了两个理论上同时运行的CPU线程;因此,001122..44的输出正在按预期工作。

答案 1 :(得分:1)

当连接runnable启动时,它首先等待500 mil,然后打印一个数字。

1和3都同时启动,但是你告诉主要的威胁是等待j1结束。与此同时,j3也在打印。所以你在输出上重复了数字。

当j1完成时,你存在join()锁定,并且j2启动,但随后它到达程序结束。有时它可能无法及时完成。

如果您希望o更好地了解正在发生的事情,请在每个线程中添加一个名称,例如:

public class Join extends Thread {
   private final String name;

    public Join(String name){ this.name=name; }
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                System.out.println(e);
            }
            System.out.println(name+": "+i);
        }
    }
}

您可以使用this教程,它看起来与您的示例非常相似

答案 2 :(得分:1)

要更好地理解输出,请按以下步骤更改代码

join

中添加构造函数
 public join(String name){
    super(name);
 }

将print statement更改为

System.out.println(i+" from "+Thread.currentThread().getName());

按如下方式更改线程创建:

join j1 = new join("j1");
join j2 = new join("j2");
join j3 = new join("j3");

输出:

0 from j3
0 from j1
1 from j3
1 from j1
2 from j3
2 from j1
3 from j3
3 from j1
4 from j3
4 from j1
0 from j2
1 from j2
2 from j2
3 from j2
4 from j2

join()允许线程死亡。

序列:

  1. j3 开始了。睡了500毫秒并打印0。
  2. j1 并行启动。睡眠时间为500毫秒并打印0.如果您将睡眠时间从 500 ms更改为 50 ms,则输出在 j1 之间无法预测 j3 ,它们并行运行。
  3. 两者并行运行,后来打印1,2,3,4,睡眠时间为500毫秒。
  4. 通过调用join(),您正在等待 j1 死亡。
  5. 您已经 j1 死亡后开始 j2 j3 到那时已经完成了。