【问题标题】:Thread.join() to guarantee execution orderThread.join() 保证执行顺序
【发布时间】:2016-01-09 19:34:48
【问题描述】:

我已阅读Thread 文档并查看了许多示例,但我无法让我的代码正常运行。我想保证Threads 是按照t2、t3、t1 的顺序执行的,并且我正在尝试使用join() 方法来执行此操作。

据我了解,join() 将确保调用它的 Thread 实例将一直运行到被杀死,然后再继续执行下一个 Thread。这是我的代码:

public class ThreadyKrueger extends Thread {

private Thread t;
private String threadName;

public ThreadyKrueger(String name) {
    this.threadName = name;
    System.out.println("Creating thead, \"" + this.threadName + "\"");
}
@Override
public void run() {
    try {
        System.out.println("Job being run by " + this.threadName);
        Thread.sleep(200);
    } catch (InterruptedException e) {
        System.out.println("Thread " + this.threadName + " interrupted!");
    }
    System.out.println(this.threadName + " exiting...");
}
@Override
public void start() {
    System.out.println("Starting " + this.threadName);
    if (t == null) {
        t = new Thread(this, this.threadName);
    }
    t.start();
}

}

public class ThreadMain {

public static void main(String[] args) throws InterruptedException {
    //ensure order is t2, t3, t1
    ThreadyKrueger t2 = new ThreadyKrueger("T2");
    ThreadyKrueger t3 = new ThreadyKrueger("T3");
    ThreadyKrueger t1 = new ThreadyKrueger("T1");        
    t2.start();
    t2.join();        
    t3.start();
    t3.join();
    t1.start();
}

我得到的输出每次都不同,但例如:

Creating thead, "T2"
Creating thead, "T3"
Creating thead, "T1"
Starting T2
Starting T3
Starting T1
Job being run by T2
Job being run by T3
Job being run by T1
T1 exiting...
T2 exiting...
T3 exiting...

显然 T2 在 T3 开始之前没有被杀死,依此类推。我缺少什么(除了在复制/粘贴中丢失的一些缩进和括号)。谢谢。

【问题讨论】:

  • 你为什么要创建一个Thread 来启动另一个Thread(你没有join)?这是非常倒退的。你的Krueger 应该是Runnable
  • 我明白了——我正在试验 Runnable 实现和 Thread 实现,看来我已经混合了这两者。感谢您指出这一点。
  • 如果你想要一个特定的执行顺序你为什么要使用线程?
  • 我意识到这一点。这只是为了了解join() 方法的作用。
  • 作为 SO 新手的一个一般性问题:我可以做些什么来改进我的问题以供将来参考,因为这被否决了?

标签: java multithreading java-threads


【解决方案1】:

您从另一个线程启动一个线程,但加入到起始线程 (ThreadyKrueger)。 ThreadyKrueger 在启动内线程后立即完成,然后执行 run() 方法..

使用Runnable 而不是继承Thread,以避免此类问题。

另外,我认为在单独的线程中按顺序运行任务没有意义。我会创建一个Runnable 的列表/队列,然后在循环中处理它。

【讨论】:

  • 谢谢。我正在尝试两种实现(扩展Thread 和实现Runnable,并错误地在两者之间混合了一些代码。现在很明显它已经被指出了!
【解决方案2】:

您在主线程中创建的线程已按顺序正确执行,但是由于每个线程都在启动自己的线程,因此这些线程是并发运行的……无需创建这些“子线程”。移除被覆盖的start 方法。

【讨论】:

    【解决方案3】:

    在你的 main 方法中,当你执行例如 t2.start 时,你正在创建另一个线程,当你执行 t.start();

    更好的方法是删除 ThreadyKrueger 类中的 start 方法。

    【讨论】:

      猜你喜欢
      • 2016-04-29
      • 2021-03-07
      • 2018-01-07
      • 1970-01-01
      • 2014-07-22
      • 1970-01-01
      • 2016-05-02
      • 2013-11-25
      • 2011-01-13
      相关资源
      最近更新 更多