Java多线程

线程的状态#

NEW》start()》Runable
Runable》获取CPU》Running
Running》yield()》Runable
Running》Run()完成或异常退出》Dead
Running》join(),sleep()》Blocked
Blocked》sleep()结束,join()中断,I/O完成》Runable
Running》synchronized》锁定Blocked
Running》synchronized,wait(),释放锁》等待Blocked
锁定Blocked》同步锁被释放》Runable
等待Blocked》恢复锁notify()/notifyAll(),interrupt()》锁定Blocked

线程在Running的过程中可能会遇到阻塞(Blocked)情况

  1. 调用join()和sleep()方法,sleep()时间结束或被打断,join()中断,IO完成都会回到Runnable状态,等待JVM的调度。
  2. 调用wait(),使该线程处于等待池(wait blocked pool),直到notify()/notifyAll(),线程被唤醒被放到锁定池(lock blocked pool ),释放同步锁使线程回到可运行状态(Runnable)
  3. 对Running状态的线程加同步锁(Synchronized)使其进入(lock blocked pool ),同步锁被释放进入可运行状态(Runnable)。

此外,在runnable状态的线程是处于被调度的线程,此时的调度顺序是不一定的。Thread类中的yield方法可以让一个running状态的线程转入runnable

线程休眠

使用 TimeUnit 来替代 sleep。

​ TimeUnit是java.util.concurrent包下面的一个类,TimeUnit提供了可读性更好的线程暂停操作,通常用来替换Thread.sleep(),在很长一段时间里Thread的sleep()方法作为暂停线程的标准方式,几乎所有Java程序员都熟悉它,事实上sleep方法本身也很常用而且出现在很多面试中。如果你已经使用过Thread.sleep(),当然我确信你这样做过,那么你一定熟知它是一个静态方法,暂停线程时它不会释放锁,该方法会抛出InterrupttedException异常(如果有线程中断了当前线程)。但是我们很多人并没有注意的一个潜在的问题就是它的可读性。Thread.sleep()是一个重载方法,可以接收长整型毫秒和长整型的纳秒参数,这样对程序员造成的一个问题就是很难知道到底当前线程是睡眠了多少秒、分、小时或者天。

TimeUnit.SECONDS.sleep(4);

​ 除了sleep的功能外,TimeUnit还提供了便捷方法用于把时间转换成不同单位。

TimeUnit.SECONDS.toMillis(44); #返回44,000

posted @ 2018-11-28 17:43  枫子_dan  阅读(110)  评论(0编辑  收藏  举报