Java在完成线程之前执行下一个任务

时间:2016-02-16 23:47:39

标签: java multithreading

我有一个简单的任务,使用java访问相同的var来构建3个线程,获取值,包含它,然后将其存储回来。这里是快照代码

class DATA{
    int x;
}

class ThreadDemo extends Thread {
   private Thread t;
   private String threadName;
   DATA data;

   ThreadDemo( String name,  DATA data){
       threadName = name;
       this.data = data;
   }
   public void run() {
        for(int x = 0; x < 10; x++){
            int tmp = this.data.x;
            tmp++;
            System.out.println("Thread " +  threadName + " for " + x + " inc val = " + tmp);
            this.data.x = tmp;
        }
     System.out.println("Thread " +  threadName + " exiting.");
   }

   public void start ()
   {
      System.out.println("Starting " +  threadName );
      if (t == null)
      {
         t = new Thread (this, threadName);
         t.start ();
      }
   }

}

public class TestThread {
   public static void main(String args[]) {

      DATA data = new DATA();

      ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", data );
      ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", data );
      ThreadDemo T3 = new ThreadDemo( "Thread - 3 ", data );

      T1.start();
      T2.start();
      T3.start();

      // wait for threads to end
      try {
         T1.join();
         T2.join();
         T3.join();
      } catch( Exception e) {
         System.out.println("Interrupted");
      }
        System.out.println("Final falue = " + data.x);
   }
}

我想问的是为什么

 System.out.println("Final falue = " + data.x);

在3线程完成之前执行?该代码产生了这个结果之一

Starting Thread - 1 
Starting Thread - 2 
Thread Thread - 1  for 0 inc val = 1
Starting Thread - 3 
Thread Thread - 2  for 0 inc val = 2
Thread Thread - 2  for 1 inc val = 3
Thread Thread - 1  for 1 inc val = 2
Thread Thread - 3  for 0 inc val = 4
Thread Thread - 3  for 1 inc val = 5
Thread Thread - 2  for 2 inc val = 4
Final falue = 2 //HERE WHY IS THIS
Thread Thread - 2  for 3 inc val = 5
Thread Thread - 3  for 2 inc val = 6
Thread Thread - 3  for 3 inc val = 7
Thread Thread - 1  for 2 inc val = 3
Thread Thread - 3  for 4 inc val = 8
Thread Thread - 3  for 5 inc val = 9
Thread Thread - 2  for 4 inc val = 6
Thread Thread - 3  for 6 inc val = 10
Thread Thread - 3  for 7 inc val = 11
Thread Thread - 1  for 3 inc val = 4
Thread Thread - 3  for 8 inc val = 12
Thread Thread - 3  for 9 inc val = 13
Thread Thread - 2  for 5 inc val = 7
Thread Thread - 3  exiting.
Thread Thread - 1  for 4 inc val = 5
Thread Thread - 1  for 5 inc val = 6
Thread Thread - 2  for 6 inc val = 8
Thread Thread - 1  for 6 inc val = 7
Thread Thread - 2  for 7 inc val = 9
Thread Thread - 1  for 7 inc val = 8
Thread Thread - 2  for 8 inc val = 10
Thread Thread - 1  for 8 inc val = 9
Thread Thread - 2  for 9 inc val = 11
Thread Thread - 1  for 9 inc val = 10
Thread Thread - 2  exiting.
Thread Thread - 1  exiting.

不应该等到

      try {
         T1.join();
         T2.join();
         T3.join();
      } catch( Exception e) {
         System.out.println("Interrupted");
      }

完成,然后执行下一个任务?

2 个答案:

答案 0 :(得分:4)

这是因为您在Thread方法中创建并启动了新的ThreadDemo.start() - 您正在调用join的实际实例是{{ 1}},从来没有&#34;正确&#34;启动。

只需删除ThreadDemo方法(或至少调用ThreadDemo.start()而不是创建新主题。)

答案 1 :(得分:0)

开始使用CountDownLatch而不是加入。

http://javarevisited.blogspot.ca/2012/07/countdownlatch-example-in-java.html

它如此简单

public class TestCountDownException {

public static void main(String[] args) {
    try {
        final CountDownLatch cdl = new CountDownLatch(2);
        new Thread(new Runnable() {
            @Override
            public void run() {
                cdl.countDown();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                cdl.countDown();
            }
        }).start();
        cdl.await();
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
}

}