一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第19天,点击查看活动详情。
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;
}
}
}
if (millis < 0) { throw new IllegalArgumentException("timeout value is negative");}
判断超时时间是否小于 0,如果小于0,则会抛出IllegalArgumentException异常
if (millis == 0) { while (isAlive()) { wait(0); } }
millis 等于 0 表示无限等待,直到线程执行完为止
isAlive判断子线程是否为活跃线程,是则一直等待
wait(delay);
可以看出,join()方法底层还是通过wait()实现的。
在实际的使用中,如果在main方法中启用了一个新的线程,并且在主线程中调用了join()方法,则实际的效果则会表现为: 主线程会先等子线程执行完成后才继续执行。
yield()
public static native void yield();
yield()方法是调用的java本地方法,底层是由C或者C++实现的。
yield()方法含义是:给线程调度器一个当前线程愿意出让 CPU 使用权的信息。但是线程调度器并不是一定会立马响应这个请求,甚至不会响应。
sleep()
public static native void sleep(long millis) throws InterruptedException;
sleep使当前线程(即调用sleep方法的线程暂停一段时间),给其它的线程运行的机会,而且是不考虑其它线程的优先级的,而且不释放资源锁,也就是说如果有synchronized同步块,其它线程仍然是不能访问共享数据的
当线程执行了sleep方法之后,线程将转入到睡眠状态,直到时间结束
sleep方法需要抛出或者捕获异常,因为线程在睡眠中可能被打断,
wait()和wait(time)
wait()的作用是让当前线程进入等待状态,wait()也会让当前线程释放它所持有的锁。 直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,当前线程才会被唤醒进入就绪状态
public final void wait() throws InterruptedException {
wait(0);
}
public final native void wait(long timeout) throws InterruptedException;
wait() 实现也是调用的wait(long timeout)方法,时间传入的是0
wait(long timeout)方法底层是调用的java本地方法,由C或者C++实现。