Java多线程-join的使用

Posted Alan Lau

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程-join的使用相关的知识,希望对你有一定的参考价值。

join的作用

join的作用是等待线程对象销毁。

方法join 的作用是使所属的线程对象 x 正常执行 run() 方法中的任务,而使当前线程 z 进行无限期的阻塞,等待线程 x 销毁之后再继续执行当前线程 z 后面的代码。

注意:

如果方法 join() 与 interrupt() 方法相遇,则会抛出异常。示例如下:

public class JoinException {
    public static void main(String[] args) {
        try {
            ThreadB b = new ThreadB();
            b.start();
            Thread.sleep(500);
            ThreadC c = new ThreadC(b);
            c.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class ThreadA extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                String newString = new String();
                Math.random();
            }
        }
    }

    static class ThreadB extends Thread {
        @Override
        public void run() {
            try {
                Thread a = new ThreadA();
                a.start();
                a.join();
                System.out.println("线程B在 run end 处打印了");
            } catch (InterruptedException e) {
                System.out.println("线程B在 catch 处打印了");
                e.printStackTrace();
            }
        }
    }

    static class ThreadC extends Thread {
        private ThreadB threadB;

        public ThreadC(ThreadB threadB) {
            this.threadB = threadB;
        }

        @Override
        public void run() {
            threadB.interrupt();
        }
    }
}

运行结果如下:

 

 

join()会释放锁

Thread.sleep()不释放锁。而 join() 方法会释放锁

方法 join(long) 的功能在内部是使用 wait(long) 方法来实现的,所以 join(long) 方法具有释放锁的特点。

方法 join(long) 源代码如下:

 

方法 join() 后面代码提前运行:出现意外

join(long millis) 设置了时间参数的 join() 容易出现意外。示例如下:

tips:最后的解决方案是把 b.join(2000) 替换成 b.join()

public class JoinTest {
    public static void main(String[] args) {
        try {
            ThreadB b = new ThreadB();
            ThreadA a = new ThreadA(b);
            a.start();
            b.start();
            b.join(2000);
            System.out.println("    main edn " + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class ThreadA extends Thread {
        private ThreadB b;

        public ThreadA(ThreadB b) {
            this.b = b;
        }

        @Override
        public void run() {
            synchronized (b) {
                try {
                    System.out.println("begin A ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis());
                    Thread.sleep(5000);
                    System.out.println("    end A ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class ThreadB extends Thread {
        @Override
        synchronized public void run() {
            try {
                System.out.println("begin B ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis());
                Thread.sleep(5000);
                System.out.println("    end B ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果分析:

 

 

 

 

以上是关于Java多线程-join的使用的主要内容,如果未能解决你的问题,请参考以下文章

Java 多线程 Fork/Join

java多线程wait notify join

java多线程16:join()的使用

Java多线程神器:join使用及原理

Java多线程中的join方法

java多线程基本概述——join()方法