JUC(3)

77 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

3.6run方法和start方法

直接调用 run 是在主线程中执行了 run,没有启动新的线程 使用 start 是启动新的线程,通过新的线程间接执行 run 中的代码

3.7sleep和yield

sleep

  1. 调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞)

  2. 其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException,这时的打断标记还是false

  3. 睡眠结束后的线程未必会立刻得到执行

  4. 建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性

上述代码作用与Thread.sleep(1000)一模一样

yield

  1. 调用 yield 会让当前线程从 Running 进入 Runnable 就绪状态,然后调度执行其它线程
  2. 具体的实现依赖于操作系统的任务调度器

注意:并不是说调用了此方法后当前线程就不会在下一次调用中出现了

应用之效率(案例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 一个料理后事的机会。

  1. 错误思路
  • 使用线程对象的 stop() 方法停止线程 stop 方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁, 其它线程将永远无法获取锁
  • 使用 System.exit(int) 方法停止线程 目的仅是停止一个线程,但这种做法会让整个程序都停止
  1. 两阶段终止模式