操作系统线程状态和Java线程状态的区别与联系
操作系统
操作系统的线程有五种状态,它们分别是:新建态、就绪态、运行态、等待态、终止态
就绪态:资源齐全,处于可运行的状态
等待态:等待某一资源或锁的状态
Java虚拟机
Java虚拟机的线程分为六种状态,它们分别是:NEW、RUNNABLE、WAITING、TIMED_WAITING、BLOCKED、TERMINATED
RUNNABLE:Java虚拟机的Runnable态包含了操作系统的就绪态和运行态,也就是说,当Java虚拟机中有一个线程处于该状态时,它不仅仅可能处于运行态,它也可能处于一种需要某种资源的就绪态(比如IO资源)
WAITING:在Java虚拟机中,处于waiting态的线程必须要被其他线程给唤醒,notify()、notifyAll()方法均可唤醒处于waiting态的线程
Object.wait()、Thread.join()、LockSupport.park(),这三种方法都可以用来将一个线程设置为waiting状态。在操作系统中,处于等待态的线程是由于缺少某种资源或没有抢到锁等原因导致处于等待阻塞的一个状态。
TIMED_WAITING:超时等待态,Java虚拟机独有的状态,在超过某一时间之后,自动从超时等待态切换到RUNNABLE状态
调⽤如下⽅法会使线程进⼊超时等待状态:
Thread.sleep(long millis):使当前线程睡眠指定时间,只能使用interrupt()方法打断;
Object.wait(long timeout):线程休眠指定时间,等待期间可以通过notify()/notifyAll()唤醒;
Thread.join(long millis):等待当前线程最多执⾏millis毫秒,如果millis为0,则会⼀直执⾏;
LockSupport.parkNanos(long nanos): 除⾮获得调⽤许可,否则禁⽤当前线程进⾏线程调度指定时间;
LockSupport.parkUntil(long deadline):同上,也是禁⽌线程进⾏调度指定时间;
BLOCKED:在Java虚拟机中,处于该状态的线程必须等待锁的释放,才能进入同步区。
Java中线程状态转换图:
Java虚拟机中sleep()和wait()的区别
sleep()方法可以在任何场景下使用,而wait()方法只能在同步方法或同步代码块中使用
sleep()方法不释放锁,而wait()方法释放锁
sleep()方法会使线程处于TIMED_WAITING状态,而wait()方法会使线程处于WAITING状态
sleep()方法提前唤醒只能使用interrupt(),而wait()方法使用notify()或notifyAll()