The use of Joins in Java

Join () should be a common method we use in Java, which basically sets the current thread to WAITTING state and then waits for the calling thread to finish or be interrupted.

Join () is the method defined in Thread. Let’s look at its definition:

   /**
     * Waits for this thread to die.
     *
     * <p> An invocation of this method behaves in exactly the same
     * way as the invocation
     *
     * <blockquote>
     * {@linkplain #join(long) join}{@code (0)}
     * </blockquote>
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public final void join(a) throws InterruptedException {
        join(0);
    }

Copy the code

Let’s see how A join is used. Normally we need to call thread b.join () from thread A:

public class JoinThread implements Runnable{
    public int processingCount = 0;

    JoinThread(int processingCount) {
        this.processingCount = processingCount;
        log.info("Thread Created");
    }

    @Override
    public void run(a) {
        log.info("Thread " + Thread.currentThread().getName() + " started");
        while (processingCount > 0) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                log.info("Thread " + Thread.currentThread().getName() + " interrupted");
            }
            processingCount--;
        }
        log.info("Thread " + Thread.currentThread().getName() + " exiting");
    }

    @Test
    public void joinTest(a)
            throws InterruptedException {
        Thread t2 = new Thread(new JoinThread(1));
        t2.start();
        log.info("Invoking join");
        t2.join();
        log.info("Returned from join");
        log.info("t2 status {}",t2.isAlive()); }}Copy the code

We called t2.join() on the main thread, and the main thread will wait for t2 to complete.

06:17:14.775 [main] info.flydean. JoinThread - Thread Created 06:17:14.779 [main] info.flydean. JoinThread - Invoking JOIN 06:17:14.779 [thread-0] infocom.flydean. JoinThread - Thread thread-0 started 06:17:15.783 [thread-0] INFO JoinThread - Thread-0 Withdraw 06:17:15.783 [main] INFO com.flydean.JoinThread - Returned from Join 06:17:15.783 [main] info.flydean. JoinThread - t2 status falseCopy the code

Join () returns immediately when the thread has finished executing or has not yet started executing:

Thread t1 = new SampleThread(0);
t1.join();  //returns immediately
Copy the code

Join also has two methods that take time parameters:

public final void join(long millis) throws InterruptedException
Copy the code
public final void join(long millis,int nanos) throws InterruptedException
Copy the code

If the thread called does not return within a given time, the main thread will continue executing:

    @Test
    public void testJoinTimeout(a)
            throws InterruptedException {
        Thread t3 =  new Thread(new JoinThread(10));
        t3.start();
        t3.join(1000);
        log.info("t3 status {}", t3.isAlive());
    }
Copy the code

The above example will print:

06:30:58. [the main] INFO 159 com. Flydean. JoinThread - Thread Created 06:30:58. 163 / Thread - 0 INFO com. Flydean. JoinThread - Thread Thread-0 started 06:30:59.172 [main] info.flydean. JoinThread - t3 status TrueCopy the code

Join() also has a happen-before feature. If thread T1 calls t2.join(), all changes to T2 will be visible to T1 when T2 returns.

This happens -before rule was mentioned earlier when we talked about volatile. Let’s look at an example:

    @Test
    public void testHappenBefore(a) throws InterruptedException {
        JoinThread t4 =  new JoinThread(10);
        t4.start();
        // not guaranteed to stop even if t4 finishes.
        do {
            log.info("inside the loop");
            Thread.sleep(1000);
        } while ( t4.processingCount > 0);
    }
Copy the code

When we run it, we can see that the while loop continues, even though the variable in T4 has changed to 0.

So if we need to use it in this case, we need to use join () or some other synchronization mechanism.

Examples of this article can be found at github.com/ddean2009/l…

See flydean’s blog for more tutorials