Java 主题:给定程序运行不正常

Java Thread : Given program isn't behaving properly

import java.lang.*;

class MyRun implements Runnable 
{
  public static int start = 0;
  public void run() 
  {
    int myCounter = 0;
    System.out.println(Thread.currentThread().getName()+" is waiting on start flag");
    while(start<1)
    {
      // just waiting...        
    }
    while(myCounter<5) 
    {
      myCounter++;
      System.out.println(Thread.currentThread().getName()+" : "+myCounter);
      try 
      {
        Thread.sleep(1000);
      } catch(Exception ex) {}
    }
    System.out.println(Thread.currentThread().getName()+" stopped and start="+start);
  }
}

public class test 
{
  public static void main(String[] args) 
  { 
    Thread[] threads = new Thread[10];
    for(int i=0; i<10; i++) 
    {
      int p = i+1;
      threads[i] = new Thread(new MyRun());
      threads[i].setName("TH"+p);
      threads[i].setPriority(p);
      threads[i].start();
    }
    MyRun.start=1; // signaling GO
  }
}

输出:

TH1 is waiting on start flag
TH2 is waiting on start flag
TH3 is waiting on start flag
TH4 is waiting on start flag
TH5 is waiting on start flag
TH6 is waiting on start flag
TH8 is waiting on start flag
TH7 is waiting on start flag
TH9 is waiting on start flag
TH10 is waiting on start flag
TH10 : 1
TH10 : 2
TH10 : 3
TH10 : 4
TH10 : 5
TH10 stopped and start=1

我期待所有线程的输出,因为开始标志设置为 1,但只执行名称为 TH10 的线程。

你能帮我找出这段代码中到底发生了什么吗?

我想用这样的代码做什么?

答案:尝试分析线程的优先级(清除我的线程概念,特别是多线程与可运行的共享静态变量)。

提前致谢,如果您需要我这边的任何信息,请告诉我。

更新:将所有线程视为马,当MyRun.start设置为1时(它应该被视为所有马的GO信号)但只有第10匹马在信号之后运行。

这段代码至少有两个问题:

  • 它使用了一个 public 非同步变量 (start),就多线程而言,这总是一种代码味道 => 不能保证您的线程看到正确的值start
  • 它不等待线程完成它们的任务

实现这种事情的正确方法是使用 java.util.concurrent 包中的范例。在这种情况下,这将是 CountDownLatches

Javadoc 中提供的示例实际上与您在此尝试实现的非常接近(一起启动所有线程,等待它们完成),因此我正在复制它。 MyRun就是下面的Worker;在 doWork() 中,请实现您的 run() 方法的内容

startSignal "latches" 启动的所有线程里面都是"awaiting" 而已。 doneSignal"latches"程序结束(main)一次结束所有线程已经"counted down"

 class Driver { // ...
   void main() throws InterruptedException {
     CountDownLatch startSignal = new CountDownLatch(1);
     CountDownLatch doneSignal = new CountDownLatch(N);

     for (int i = 0; i < N; ++i) // create and start threads
       new Thread(new Worker(startSignal, doneSignal)).start();

     doSomethingElse();            // don't let run yet
     startSignal.countDown();      // let all threads proceed
     doSomethingElse();
     doneSignal.await();           // wait for all to finish
   }
 }

 class Worker implements Runnable {
   private final CountDownLatch startSignal;
   private final CountDownLatch doneSignal;
   Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
      this.startSignal = startSignal;
      this.doneSignal = doneSignal;
   }
   public void run() {
      try {
        startSignal.await();
        doWork();
        doneSignal.countDown();
      } catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }