【问题标题】:Controlling the order of execution of threads控制线程的执行顺序
【发布时间】:2012-06-23 22:35:12
【问题描述】:

我正在尝试测试线程以特定顺序执行的多线程场景,因此我可以确信我在此场景中具有正确的行为。

假设: ThreadA 有方法1()2()。 ThreadB 有方法3()4()

我希望执行顺序是:

ThreadA.1() 
ThreadB.3() 
ThreadA.2()
ThreadB.4() 

我可以通过向 ThreadA 和 ThreadB 传递一个命令来告诉他们要执行什么方法以及在重新启动下一个线程之前加入每个线程来做到这一点。

我只是想知道是否有更优雅的做法。

注意,这是测试代码,我想测试某个场景。

非常感谢。

【问题讨论】:

  • 如果你想要顺序执行,那为什么要使用多个线程呢?
  • "ClassB 有方法 3() 和 4()。"然后是“classB.2()”。但是 classB 没有方法 2()...
  • 这不是首先破坏线程的意义吗?
  • 这是测试代码。我想测试某个场景。
  • 看到这个答案:*.com/questions/5461543/…

标签: java multithreading concurrency


【解决方案1】:

让每个线程等待生产者-消费者队列。将包含 Class 实例和状态变量的对象提交到队列 1。在线程 1 中,执行 classA.1() 并将对象提交到队列 2。在线程 2 中,执行 classB.2() 并将对象提交到队列1 .....

不要将连接、同步等与任何无关紧要的线程内容一起使用——你只会陷入死锁、性能不佳和噩梦般的调试。

在 P-C 队列上传递对象 - 死锁虽然并非不可能,但非常困难 :)

如果您可以在任何地方安排任何与线程无关的东西,您应该这样做。

【讨论】:

    【解决方案2】:

    嗯,这个问题被问得很糟糕(你说 classA 有方法 1() 和 2(),但是......那么你的例子根本没有遵循。

    但是,如果您想在线程之间添加一些相似的顺序而不显式地 join()ing 或 run()ing 它们,您可以让它们相互访问(例如,使用单例类,这将充当一个易于访问的中介),并且,一旦您希望一个线程等待另一个线程执行某个任务,您可以在 while 循环内的同步块中使用等待语句作为如下:

    while (!Singleton.finished()) {
        synchronized (this) {
            wait();
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果你只有执行顺序,为什么还要 2 个线程?一个接一个地执行。

      不管怎样,你可以使用下面的代码:

      void synchronized executor(){
          Thread threadA = new Thread( new Runnable(){
             @Override
             void run(){
                  classA.1();//or the equivalent object
                  Thread.notify();
             }
          }
          threadA.run();
          threadA.wait();
          Thread threadB = new Thread( new Runnable(){
             @Override
             void run(){
                  classB.3();//or the equivalent object
                  Thread.notify();
             }
          }
          threadB.run();
          threadB.wait();
          Thread threadA = new Thread( new Runnable(){
             @Override
             void run(){
                  classA.2();//or the equivalent object
                  Thread.notify();
             }
          }
          threadA.run();
          threadA.wait();
          Thread threadB = new Thread( new Runnable(){
             @Override
             void run(){
                  classB.4();//or the equivalent object
                  Thread.notify();
             }
          }
          threadB.run();
      }
      

      如您所见,没有优雅的方法可以做到这一点。

      【讨论】:

      • 我更新了问题以使事情更清楚。谢谢你们的cmets。