开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情
3.6run方法和start方法
直接调用 run 是在主线程中执行了 run,没有启动新的线程 使用 start 是启动新的线程,通过新的线程间接执行 run 中的代码
3.7sleep和yield
sleep
-
调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞)
-
其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException,这时的打断标记还是false
-
睡眠结束后的线程未必会立刻得到执行
-
建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性
上述代码作用与Thread.sleep(1000)一模一样
yield
- 调用 yield 会让当前线程从 Running 进入 Runnable 就绪状态,然后调度执行其它线程
- 具体的实现依赖于操作系统的任务调度器
注意:并不是说调用了此方法后当前线程就不会在下一次调用中出现了
应用之效率(案例2):防止CPU占用100%
while(true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
sleep适用于无需锁同步的场景
3.8 join方法
join():等待线程运行结束
join(long n):等待线程运行结束,最多等待 n 毫秒
join其实就是同步方法,什么意思呢!就是说调用了join后就得等待另一个线程结束,这与同步(得等待另一个线程结束才能继续工作)的原理是相吻合的
等待多个结果
等待多个结果与等待一个结果差不多,具体语境具体分析即可
3.9 interrupt 方法详解
可以打断 阻塞(sleep,wait,join) 的线程
这几个方法都会让线程进入阻塞状态 打断 sleep 的线程, 会清空打断状态,以 sleep 为例
会抛出sleep interrupted的异常,打断标记为false
打断正常运行的线程
打断并不是说明可以将其他线程直接kill掉,还得通过添加打断标记进行判断
上述例子说明仅仅使用 t2.interrupt();是无法退出死循环的
3.10 模式之两阶段终止
在一个线程 T1 中如何“优雅”终止线程 T2?这里的【优雅】指的是给 T2 一个料理后事的机会。
- 错误思路
- 使用线程对象的 stop() 方法停止线程 stop 方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁, 其它线程将永远无法获取锁
- 使用 System.exit(int) 方法停止线程 目的仅是停止一个线程,但这种做法会让整个程序都停止
-
两阶段终止模式