Java join()方法、wait()方法和sleep()方法的理解

join()

join()方法来自于Thread,join()方法的作用是 阻塞 调用该方法的线程,使其进入 TIMED_WAITING 状态,直到被调用的线程执行完毕,原方法继续执行。

如以下代码,在主线程中调用join()方法,会首先执行run()方法中的代码。

当我们把join()方法给注释掉,会发现,首先执行了主线程的代码。

即 调用join()方法阻塞了主线程,当run()方法执行完毕,主线程方法继续执行

    public static void main(String[] args) throws InterruptedException {
        WaitJoinAndSleep w = new WaitJoinAndSleep();

        Thread tOne = new Thread(w);
        tOne.setName("1号选手");
        tOne.start();
        tOne.join();
        System.out.println("main finished");

    }

    @Override
    public void run() {
        System.out.println("who first in:"+Thread.currentThread().getName());
            System.out.println("Thread Name:+"+Thread.currentThread().getName());
    }

//输出
who first in:1号选手
Thread Name:+1号选手
main finished

//注释掉tOne.join()后输出
main finished
who first in:1号选手
Thread Name:+1号选手

join()方法源码

通过join()方法源码我们可以发现,join()方法最终是调用了wait()方法

    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;
            }
        }
    }

wait()

wait()方法来自于Object。

wait()方法的作用是让当前线程等待,即执行wait方法的线程等待,释放锁。等待其它线程调用notify()方法时再继续运行。

如下代码,当主线程调用start()方法。此时并不会运行run()方法。因为此时锁被主线程占有。当主线程中代码调用wait()方法,主线程释放锁,线程one获得锁。在run()方法中执行notify()方法后,主线程被唤醒,继续执行。

总结:wait()方法是让运行它自身的线程等待。需要注意的是wait(),notify()和notifyAll()方法需要在synchronized中调用

   public static void main(String[] args) throws InterruptedException {
        WaitDemo w = new WaitDemo();
        Thread one = new Thread(w);
        synchronized (WaitDemo.class) {
            // 开始启动线程
            System.out.println("thread started:"+Thread.currentThread().getName());
            one.start();
            //  调用wait()方法
            System.out.println("begin start wait method");
            WaitDemo.class.wait();
            System.out.println("who started again");
        }
    }

    @Override
    public void run() {
        synchronized (WaitDemo.class) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("who come first:"+Thread.currentThread().getName());
            WaitDemo.class.notify();
        }
    }

// 输出
thread started:main
begin start wait method
who come first:Thread-0
who started again

sleep()

sleep()方法属于Thread

sleep()方法同样可以造成线程阻塞,结合之前的代码示例可以理解。调用sleep()方法并不会释放锁,而是让当前线程“睡眠”,持有锁的仍旧是当前线程,“睡眠时间”作为参数,时间一到代码继续运行。

与wait()方法不同的是,sleep()方法可以在任意地方调用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章