java中join()方法的使用

Java中Thread类提供join()方法。

作用:用于在当前线程A中添加别的线程B,这时线程A被阻塞,处于Blocked状态,线程B开始执行,当线程B执行完以后,线程A处于可运行状(Runnable),等待cpu的调度再执行。

用法:当前线程A必须先用myThread的start()启动线程(否则join()不会被执行),然后调用join():
//线程A中的代码
myThread.start();
myThread.join();
//线程A中的代码

实例:
1. 实现Runnable接口,重写run方法

public class MyTask implements Runnable {
        private int taskNum;
        private Thread thread = null;
        public MyTask(int num) {
            this.taskNum = num;
        }
        public MyTask(int num, Thread thread) {
            this.taskNum = num;
            this.thread = thread;
        }
        @Override
        public void run() {
            System.out.println("正在执行task " + taskNum);
            try {
                if (thread != null) {
                    System.out.println("join的线程开始执行");
                    thread.start();//****在当前线程中启动要添加的线程****//
                    thread.join();//****执行join()方法****//
                    System.out.println("join的线程执行完毕");
                    System.out.println("继续执行当前线程");
                }
                Thread.sleep(taskNum * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task " + taskNum + " 执行完毕");
        }
    }
  1. 编写测试类:
public class Main {
            public static void main(String[] args) throws InterruptedException {
                System.out.println(Thread.currentThread().getName() + "开始执行");
                Thread thread2 = new Thread(new MyTask(10));
                Thread thread1 = new Thread(new MyTask(5, thread2));
                thread1.start();
                thread1.join();
                System.out.println(Thread.currentThread().getName() + "执行完毕");
            }
        }

在main线程中添加thread1线程,main线程被阻塞,thread1开始执行;
thread1中有添加了thread2线程,thread将被阻塞,直到thread2执行完毕;
3. 结果:main开始执行–>task1开始执行–>task2开始执行–>task2执行完毕–>task1执行完毕–>main执行完毕
main开始
正在执行task 1
join的线程开始执行
正在执行task 2
task 2 执行完毕
join的线程执行完毕
继续执行当前线程
task 1 执行完毕
main执行完毕
4. JDK中join()的实现

    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) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {//****表明如果myThread.join()中的myThread执行完毕变成dead状态,则退出循环,返回调用myThread.join()的线程继续执行
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
       }

所以有两种方式调用join()方法:
(1).myThread.join();//不指定当前线程wait的时间,这会导致当前线程一直阻塞至myThread执行完毕
(2).myThread.join(long time);//指定当前线程wait时间,这回导致当前线程一直阻塞time毫秒或者myThread执行完毕
5. 测试join(long time)
修改上文的MyTask类

public class MyTask implements Runnable {
    private int taskNum;
    private Thread thread = null;

    public MyTask(int num) {
        this.taskNum = num;
    }

    public MyTask(int num, Thread thread) {
        this.taskNum = num;
        this.thread = thread;
    }

    @Override
    public void run() {
        System.out.println("正在执行task " + taskNum);
        try {
            if (thread != null) {
                System.out.println("join的线程开始执行");
                long start = System.currentTimeMillis();
                thread.start();
                thread.join(3000);
                long end = System.currentTimeMillis();
                System.out.println("join的线程执行完毕,用时" + (end - start) + "毫秒");
                System.out.println("继续执行当前线程");
            }
            Thread.sleep(taskNum * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("task " + taskNum + " 执行完毕");
    }
}
  1. 结果
    main开始执行
    正在执行task 1
    join的线程开始执行
    正在执行task 2
    task 2 执行完毕
    join的线程执行完毕,用时2000毫秒//表明join的线程执行完毕以后就返回了
    继续执行当前线程
    task 1 执行完毕
    main执行完毕
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章