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()方法可以在任意地方调用