Java线程状态转换

来源:互联网 发布:windows平板电脑 编辑:程序博客网 时间:2024/06/17 21:44



在任意一个时间点:一个线程只能有且只有其中一种状态。


新建(new)状态:创建后尚未启动的线程就是出于这种状态。


运行(Runable)状态:Runable包括了操作系统线程状态中的Running和Ready,也就是出于此状态的线程有可能正在执行,也有可能等待CPU为它分配执行时间。


无限期等待(waiting)状态:处于该状态下的线程不会被分配CPU执行时间,它们要等待被其他线程显示的唤醒。以下的方法会让线程陷入无限期的等待状态。

  1. 没有设置timeout参数的Object.wait()方法。
  2. 没有设置timeout参数的Thread.join()方法
  3. LockSupport.park()方法。

限期等待(Timed Waiting)状态:处于该状态下的线程不会被分配CPU执行时间,但是不需要等待其他线程显式的唤醒。而是在一定时间之后它们会由系统自动唤醒。一以下方法会让线程进入限期等待的状态:

  1. Thread.sleep()方法
  2. 设置了timeout参数的Object.wait()方法
  3. 设置了timeout参数的Thread.join()方法
  4. LockSupport.parkNanos()方法
  5. LockSupport.parkUntil()方法

阻塞(blocked)状态:阻塞状态,顾名思义就是线程被阻塞了,在程序等待进入同步区域的时候,线程将进入这种状态。“阻塞状态” 和“等待状态” 的区别:“阻塞状态”在等待着获取一个排它锁。如果另一个线程获得了排它锁,然而这个线程申请获得这个排它锁的时候就会进入“阻塞状态”。“等待状态”则是在等待一段时间后,或者有唤醒动作的发生。


结束(terminated)状态:已终止线程的线程状态。线程结束执行。

线程状态转换关系如图(图来自深入理解jvm虚拟机


接下来就是说明让线程进入等待状态的一些方法:

1、Object类

Object.wait()方法:让当前线程立即释放当前获得的锁并进入无线等待状态。


Object.wait(long timeout)方法:让当前线程立即释放当前获得的锁并进入限期等待状态,timeout参数的单位是毫秒。唤醒:①其他线程调用notify() 或者notifyAll()、②超过timeout毫秒之后由系统自动唤醒。


Object.wait(long timeout,int naos)方法:同wait(long timeout)方法,多出来的naos参数则是单位则是纳秒,所以如果被系统自动唤醒时间是:(timeout*1000000+naos)纳秒


notify()方法:随机唤醒一个处于“等待状态”的线程(API文档上If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation)。


notifyAll()方法:唤醒所有处于“等待状态”的线程。然后所有的线程去竞争这个排他锁(优先级高的线程获得的锁的概率大)。无论notify()方法还是notifyAll()方法不会立即释放获得的锁,而是等同步代码块执行完毕后才会释放锁。


注意:wait方法和notify方法必须是同一个锁才行。

wait方法和notify方法必须在同步代码块中使用。

2、Thread类

Thread.join()方法:等待当前线程执行完毕后再执行join()后面的代码。eg:t1.join()就是等待t1线程执行完毕后,再执行后面的代码。


Thread.join(long millis)方法:至多等待millis毫秒当前线程执行,超过这个时间后,系统会主动notifyAll。


Thread.join(longmillis,int naos)方法:至多等待millis毫秒+naos纳秒当前线程执行,超过这个时间后,系统会主动notifyAll。

package com.cn.hn.test;public class ThreadSimple implements Runnable{public void run(){System.out.println(Thread.currentThread().getName()+"begin:"+ System.nanoTime());try {Thread.sleep(1800);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName()+"end:"+ System.nanoTime());};public static void main(String[] args){ThreadSimple test1 = new ThreadSimple();Thread t1 = new Thread(test1);Thread t2 = new Thread(test1);t1.setName("test1");t2.setName("test2");System.out.println("main"+Thread.currentThread().getName()+System.nanoTime());t1.start();try {t1.join();//t1.join(100);t2.start();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("main"+Thread.currentThread().getName()+System.nanoTime());}}

Thread.sleep(long millis)方法:让当前执行线程睡眠millis毫秒。超过这个时间后,系统会主动notify该线程。


Thread.sleep(long millis ,int naos)方法:让当前执行线程睡眠millis毫秒+naos纳秒,超过这个时间后,系统会主动notify该线程。


Thread.run()方法,一个线程的执行逻辑。调用Thread.start()方法会执行run()方法的内容。该方法没有返回值。如果要求有返回值,可以使用Callable()。


Thread.start()方法:启动一个线程。进入Ready状态,如果获取了cpu执行时间。然后会调用run()方法.


Thread.yield()方法:当前线程让出CPU执行时间,然后处于ready状态。然后该线程和其他处于ready状态的线程一起竞争CPU执行时间。


Thread.interrupt()方法:尝试去中断该线程。它会将当前线程中断标志位设置为TRUE。至于是否中断以及中断的过程,再开一篇说好了。


原创粉丝点击