join()方法

来源:互联网 发布:android 5.1 数据开关 编辑:程序博客网 时间:2024/05/22 01:10
public class TestJoin implements Runnable {    public static void main(String[] sure) throws InterruptedException {        Thread t = new Thread(new TestJoin());        long start = System.currentTimeMillis();        t.start();        t.join(1000);//等待线程t 1000毫秒        System.out.println(System.currentTimeMillis()-start);//打印出时间间隔        System.out.println("Main finished");//打印主线程结束    }    @Override    public void run() {    //理解这里为何不用this关键字,this指代new TestJoin(),而currentThread()指代new Thread(new TestJoin())        synchronized (Thread.currentThread()) {            for (int i = 1; i <= 5; i++) {                try {                    TimeUnit.SECONDS.sleep(1);//睡眠5秒,循环是为了方便输出信息                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println("睡眠" + i);            }            System.out.println("TestJoin finished");//t线程结束        }    }} 


jdk中join方法的源码

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()) {                long delay = millis - now;                if (delay <= 0) {                    break;                }                wait(delay);                now = System.currentTimeMillis() - base;            }        }    }

join方法是依靠wait方法来实现的, 并且join方法是一个同步方法

从代码上看,如果线程被生成了,但还未被起动,调用它的 join() 方法是没有作用的,将直接继续向下执行
Join方法实现是通过wait(小提示:Object 提供的方法)。 当main线程调用t.join时候,main线程会获得线程对象t的锁(wait 意味着拿到该对象的锁),调用该对象的wait(等待时间),直到该对象唤醒main线程 ,比如退出后。这就意味着main 线程调用t.join时,必须能够拿到线程t对象的锁


所以上述代码的执行结果分两种情况,如果主方法中的 t.join(1000) 方法先获取锁, 执行wait方法, 然后当前线程阻塞, 释放对象锁, 接着线程t启动获取对象锁, 休眠5秒并继续持有对象锁, 然后释放锁, wait方法虽然阻塞1s就结束, 但是因为未能继续获取锁, 只能等待t线程休眠5s释放锁后再持有锁, 即main方法退出持续了5s

如果是t线程先获取锁, 则main方法退出则持续了5+1s ??? 实际上怎么都是5s why??????????


注意, wait方法的执行, 需要先获取锁, 在进入阻塞状态后会释放锁, wait在唤醒后继续向下执行的前提是需要再次获取锁

原创粉丝点击