Search code examples
javamultithreadingjava-6

Can this thread be alive and how to use java.lang.Thread.join() method


I have read some SO question and docs before but do not find my response :

So...

public class MyThread extends Thread {
  public MyThread() {
    this.setName("MyThread-" + System.currentTimeMillis());
    this.start();
  }

  public MyThread(long millis) throws InterruptedException {
    this.setName("MyThread-" + System.currentTimeMillis());
    this.join(millis);
    this.start();
  }

  @Override
  public void run() {
    System.out.println("I am running...");
    // This thread does not sleep... no Thread.sleep() in run method.
    // Do some things like requesting a database
    // Database response happens in less time that the timeout
  }
}

public class MyClass {

  public MyClass(){
    for (int i = 0; i < 5; i++) {
      Thread t1 = new MyThread();
      t1.join(5000);
      if (t1.isAlive()) {
        System.out.println("I'm alive");
        // do some things
      } else {
        System.out.println("I'm not alive");
      }

      Thread t2 = new MyThread(5000);
      if (t2.isAlive()) {
        System.out.println("I'm alive");
        // do some things
      } else {
        System.out.println("I'm not alive");
      }

    }
  }
}

It seems it can not be but could one of the t1 be alive ? What about t2 ? What happend when I call join() after start()

For information, I am using :

  • JVM: Java HotSpot(TM) Client VM (20.45-b01, mixed mode, sharing)
  • Java: version 1.6.0_45, vendor Sun Microsystems Inc.

Update after reading some of your responses

If I understand, a better implementation would be something like :

public class MyThread extends Thread {
  public MyThread() {
    super("MyThread-" + System.currentTimeMillis());
  }

  @Override
  public void run() {
    System.out.println("I am running...");
    // This thread does not sleep... no Thread.sleep() in run method.
    // Do some things like requesting a database
    // Database response happens in less time that the timeout
  }
}

public class MyClass {

  public MyClass(){
    for (int i = 0; i < 5; i++) {
      Thread t1 = new MyThread();
      t1.start();
      t1.join(5000);

      if (t1.isAlive()) {
        System.out.println("I'm alive");
        // do some things
      } else {
        System.out.println("I'm not alive");
      }
    }
  }
}

Both responses have helped me a lot : https://stackoverflow.com/a/29775219/1312547 and https://stackoverflow.com/a/29775083/1312547


Solution

  • Notice that although the (JDK 7) documentation for Thread.join(long) says

    Waits at most millis milliseconds for this thread to die.

    It also continues with

    This implementation uses a loop of this.wait calls conditioned on this.isAlive.

    And Thread.isAlive says:

    A thread is alive if it has been started and has not yet died.

    So with your code:

    • When calling t1.isAlive(), it is always false since you joined after starting the thread (from the constructor).
    • When calling t2.isAlive(), it is most of the time true since
      • you joined before starting the thread (in the constructor), which returns immediately
      • the thread has just started (in the constructor)

    So to answer your question

    It seems it can not be but could one of the t1 be alive ?

    For t1, no, as long as you wait more than the time it takes it to run. For t2, yes.