【问题标题】:is it possible to define execution order for a set of threads in java是否可以在java中定义一组线程的执行顺序
【发布时间】:2012-06-27 21:02:13
【问题描述】:

我的理解是理论上线程是并行执行的。 JVM决定;当资源可用时,从等待线程队列中选择哪个线程(基于某种算法)。

因此我们无法为线程提供/强制执行序列。

假设我的 java 应用程序有 3 个线程,t1、t2 和 t3。

出于某些特定原因;我希望线程按以下顺序执行: t3 然后 t1 然后 t2。

可以这样做吗? java是否提供了任何方法来做到这一点?

【问题讨论】:

  • 你能编辑你的帖子来解释为什么你想这样做吗?
  • 如果你想要顺序执行,那你为什么要使用线程呢?
  • 是的 - 最好的方法是将三个线程中的代码放在一个线程中。
  • @Gary 它没有我现在从事的任何工作的实际背景。我正在刷新我的理解,这个问题出现在我的脑海中。
  • @Ayusman 好吧,不。没有办法扩展最终类,但是通过正确的同步和锁存器,您可以按顺序执行线程。它看起来像:ThreadA: work(); latchB.countDown(); + ThreadB: latchB.await(); moreWork(); latchC.countDown(); 等。但是使用多线程来模拟单线程行为有点……奇怪。所以这不是技术上的矛盾,只是太复杂了。

标签: java multithreading


【解决方案1】:

使用执行器:

executor.execute(runnable1);
wait();
executor.execute(runnable2);
wait();
executor.execute(runnable3);
wait();

当然,每个 Runnable 都必须以 notify() 语句结尾。

【讨论】:

  • 抱歉,错过了notify() 评论。
  • 如果你的意思是这不是最好的方法,我完全同意。与此同时,我在 Javadoc 本身中找到了一个 Ayusman 想要做的示例,以更好的方式使用 Executor:docs.oracle.com/javase/6/docs/api/java/util/concurrent/… SerialExecutor 似乎与所要求的非常接近......
  • 不,我的意思是我误读了您的答案。我收回我的 -1 并发表评论。
  • 如果runnable在调用等待之前完成,等待不会结束。
【解决方案2】:

您无法告诉线程调度程序执行线程的顺序。如果您需要确保在线程 A 上运行的某段代码必须在线程 B 上运行的另一段代码之前运行,则必须强制执行该顺序使用锁或wait()/notify()

例如,您可以使用两个线程都可以访问的变量作为“标志”来指示线程 B 继续前进是否安全。线程 B 可以 wait() 在循环中检查该变量的值。然后当线程 B 可以安全运行时,线程 A 可以设置变量并使用 notify() 唤醒线程 B。

所以是的,可以在不同线程上发生的事情之间强制执行所需的顺序。不过,一般来说,您希望避免编写这种低级、详细的代码。很容易出错并导致微妙的、难以发现的错误。在处理多线程代码时,总是尽可能尝试使用高级构建块。

【讨论】:

    【解决方案3】:

    不要使用线程,这是直截了当的答案。

    如果您不希望代码乱序运行,那么您为什么要使用线程呢?像往常一样一步一步地执行。

    如果您希望线程的某些部分按顺序运行,则使用标准并发机制,如锁、等待/通知和信号量,但如果您只是希望整个操作在特定的顺序,然后...按顺序运行它们。没有线程。

    【讨论】:

      【解决方案4】:

      从 java 8 开始,使用CompletableFuture 变得非常容易:

      CompletableFuture.runAsync(runnable3)
                  .thenRunAsync(runnable1)
                  .thenRunAsync(runnable2);
      

      【讨论】:

        【解决方案5】:

        你可以在另一个线程上加入一个线程,这样他就会在另一个线程完成时运行。

        【讨论】:

          【解决方案6】:

          您可以设置线程的顺序。

          我试图模拟你的情况:

          public class ThreadJoinExample {
              private static final Thread FIRST = new Thread( new RunnableImpl(), "first" );
              private static final Thread SECOND = new Thread( new RunnableImpl(), "second" );
              public static void main(String[] args) {
                  //here have started current thread or "main" thread that will control above threads
                  FIRST.start();
                  //waiting 2 seconds, "stop" your current thread and after current thread will start this "t3" thread until it will dead
                  try {
                      FIRST.join(2000);
                  } catch (InterruptedException e) {
                      System.out.println();
                      e.printStackTrace();
                  }
                  SECOND.start();
                  //"stop" your current thread immediately and run "t1" thread until it will dead.
                  try {
                      SECOND.join();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  //Or we can wait for all threads and in the end - finish current main thread
                  try {
                      FIRST.join();
                      SECOND.join();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  System.out.println("Current thread is going die");
              }
          }
          class RunnableImpl implements Runnable{
          
              @Override
              public void run() {
                  System.out.println("Started thread: "+Thread.currentThread().getName());
                  try {
                      Thread.sleep(4000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  System.out.println("Thread is going die: "+Thread.currentThread().getName());
              }
          }
          

          输出:

          Started thread: first
          Started thread: second
          Thread is going die: first
          Thread is going die: second
          Current thread is going die
          

          总结: 使用 .join() 方法我们可以将当前线程移动到可运行状态,直到“加入的线程”死亡时

          【讨论】:

            猜你喜欢
            • 2011-11-27
            • 2021-08-03
            • 1970-01-01
            • 2017-08-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-14
            相关资源
            最近更新 更多