简体   繁体   中英

Java execute next task before thread finish

I have a simple assignment to build 3 thread using java accessing the same var, take the value, inc it, and then store it back. Here the snap code

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);
   }
}

What i want to ask is why

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

Being execute before the 3 thread is finishing? That code produce one of this result

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.

Isn't it should wait until the

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

done, and then execute the next task?

It's because you're creating and starting a new Thread inside your ThreadDemo.start() method - the actual instance that you are calling join on is the ThreadDemo , which is never "properly" started.

Just remove your ThreadDemo.start() method (or at least invoke super.start() instead of creating a new thread).

Start using CountDownLatch rather than join.

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

Its so simple

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);
    }
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM