JAVA thread -join

concept

join method, a special kind of wait, join the currently running thread calls the method another thread, the current thread into the blocked state until a call to join the thread that end, before proceeding.

Under normal circumstances, are the main thread to create a child thread, the thread of the call join method, the main thread enters the blocking state until the child thread end of the run.

Simple Case

public class JoinThreadDemo {

    public static void main(String[] args) {
        JoinRunnable runnable1 = new JoinRunnable();
        Thread thread1 = new Thread(runnable1, "线程1");
        System.out.println("主线程开始执行!");
        thread1.start();
//      try {
//          thread1.join();
//      } catch (InterruptedException e) {
//          e.printStackTrace();
//      }

        System.out.println("主线程执行结束!");
    }

    static final class JoinRunnable implements Runnable {
        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            System.out.println(name + "开始执行!");

            for (int i = 1; i <= 5; i++) {
                System.out.println(name + "执行了[" + i + "]次");
            }
        }
    }
}

Output:

主线程开始执行!
主线程执行结束!
线程1开始执行!
线程1执行了[1]次
线程1执行了[2]次
线程1执行了[3]次
线程1执行了[4]次
线程1执行了[5]次

Uncommented, call the join method:

主线程开始执行!
线程1开始执行!
线程1执行了[1]次
线程1执行了[2]次
线程1执行了[3]次
线程1执行了[4]次
线程1执行了[5]次
主线程执行结束!

Alternative join Case

public class JoinThreadDemo {

    public static void main(String[] args) {
        JoinRunnable runnable1 = new JoinRunnable();
        Thread thread1 = new Thread(runnable1, "线程1");
        System.out.println("主线程开始执行!");
        thread1.start();
        try {
            synchronized (thread1) {
                while (thread1.isAlive()) {
                    System.out.println("begin wait");
                    //主线程持有thread1对象锁,阻塞,一直到thread1运行结束,jvm唤醒
                    thread1.wait(0);
                    System.out.println("thread wait");
                }
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("主线程执行结束!");

    }

    static final class JoinRunnable implements Runnable {

        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            System.out.println(name + "开始执行!");

            for (int i = 1; i <= 5; i++) {
                System.out.println(name + "执行了[" + i + "]次");
            }
        }
    }
}

Output:

主线程开始执行!
begin wait
线程1开始执行!
线程1执行了[1]次
线程1执行了[2]次
线程1执行了[3]次
线程1执行了[4]次
线程1执行了[5]次
thread wait
主线程执行结束!

In the thread1call wait, the main thread to block until the child thread thread1after the exit end of the run, jvmwill automatically wake blocked thread1threads on the subject

So is it possible not to use thread1the object blocking it?

The following is not to use thread1case objects blocking the main thread

Alternative join Case 2

public class JoinThreadDemo {

    public static void main(String[] args) {
        Object lock = new Object();
        Thread thread1 = new Thread(() -> {
            String name = Thread.currentThread().getName();
            System.out.println(name + "开始执行!");

            for (int i = 1; i <= 5; i++) {
                System.out.println(name + "执行了[" + i + "]次");
            }
        }, "线程1");
        System.out.println("主线程开始执行!");
        thread1.start();

        //thread2自旋唤醒阻塞在lock对象上的主线程
        Thread thread2 = new Thread(new Thread() {
            @Override
            public void run() {
                while (!thread1.isAlive() && !Thread.currentThread().isInterrupted()) {
                    synchronized (lock) {
                        System.out.println("enter");
                        lock.notifyAll();
                        System.out.println("exit");
                    }
                }
            }
        }, "线程2");
        thread2.start();

        try {
            synchronized (lock) {
                while (thread1.isAlive()) {
                    System.out.println("bb");
                    lock.wait();
                    //停止thread2自旋
                    thread2.interrupt();
                    System.out.println("tt");
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("主线程执行结束!");
    }
}

Output:

主线程开始执行!
bb
线程1开始执行!
线程1执行了[1]次
线程1执行了[2]次
线程1执行了[3]次
线程1执行了[4]次
线程1执行了[5]次
enter
exit
enter
exit
tt
主线程执行结束!

Here to add a thread thread2for special spin wake up the main thread

Used to replace a case of, thread1after the end of the thread, jvmwake up the main thread operations

join Principle

Block the main thread

Thread class, join Source:

//Thread类中
public final void join() throws InterruptedException {
    join(0);
}


public final synchronized void join(long millis) throws InterruptedException {
    long base = System.currentTimeMillis();  //获取当前时间
    long now = 0;

    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (millis == 0) {    //这个分支是无限期等待直到b线程结束
        while (isAlive()) {
            wait(0);
        }
    } else {    //这个分支是等待固定时间,如果b没结束,那么就不等待了。
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
}

join members of the method has synchronized, a locked object is an object that calls the method, namely the child thread thread1, the main thread that is holding the thread1object lock

Can debug their own, find the source of the threads join into the main thread

Wake up the main thread

Child thread thread1when finished, and jvmwill automatically wake up blocked thread1on the subject of the thread, in our case that is the main thread. At this point, thread1the thread object notifyall, then the main thread also will be able to continue to run down the

reference

Thread class join () method Principle

Java Thread the join () of inquisitive

Multi-threaded Java Study --yield () method join () method

sleep, yield, wait, join the difference (Ali)

who and when notify the thread.wait() when thread.join() is called?

Guess you like

Origin www.cnblogs.com/hongdada/p/11739311.html