Java线程的六种状态

根据 java.lang.Thread.State 中的描述Thread有处于以下6种状态中的一种:

NEW(初始状态):A thread that has not yet started is in this state

RUNNABLE(就绪状态):A thread executing in the Java virtual machine is in this state

BLOCKED(阻塞状态):A thread that is blocked waiting for a monitor lock is in this state

WAITING(等待):A thread that is waiting indefinitely for another thread to perform a particular action is in this state

TIMED_WAITING(超时等待):A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state

TERMINATED(终止状态):A thread that has exited is in this state

A thread can be in only one state at a given point in time. These states are virtual machine states which do not reflect any operating system thread states.


 

状态一  NEW(初始状态)

实现Runnable接口或者继承Thread类可以得到一个线程类,new一个实例出来,就得到了一个处于初始状态的线程。

状态二  RUNNABLE(就绪状态)

调用线程的start(),此线程就进入了就绪状态

就绪状态只说明该线程具有运行的资格,但是调度程序没有挑选到你,你就永远处于就绪状态

当前线程sleep()方法结束,其他线程join()方法结束,等待用户输入完毕,某个线程拿到对象锁,都会让线程进入就绪状态

当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态

锁池里的线程拿到对象锁之后,进入就绪状态

线程调度程序从可运行池中选择一个线程作为当前线程时,线程状态会变为运行中状态,这是线程进入运行状态的唯一方式

状态三  BLOCKED(阻塞状态)

该状态是线程阻塞在进入synchronized关键字修饰的方法或者代码块时的状态。

状态四  WAITING(等待)

处于这种状态的线程不会被分配CPU执行时间,且要等待被显式的唤醒,否则线程会无限期等待的状态。

状态六  TIMED_WAITING(超时等待)

处于这种状态的线程不会被分配CPU执行时间,不过无需无限期待等待被其他线程显式的唤醒,在达到一定时间后它们会自动唤醒。

状态七  TERMINATED(终止状态)

线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为这个线程终止了。这个线程对象也许是获得,但是它已经不是一个单独执行的线程。

线程一旦终止了,就不能复生。

在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。


 

 等待队列与同步队列

调用对象的wait()、notify()方法前,必须获得对象锁,即必须写在synchronized(obj)代码块内。

与等待队列相关的步骤图如下

同步队列状态

当前线程想要调用对象A的同步方法时,发现对象A的锁被别的线程占有,此时当前线程进入同步队列,简言之,同步队列里面放的都是想争夺对象锁的线程。

当一个线程1被另外一个线程2唤醒时,线程1进入同步队列去争夺对象锁。

同步队列是在同步环境下才有的概念,一个对象对应一个同步队列。


 

 几个重要的方法比较

Thread.sleep(long millis)  // Thread类的静态方法。一定是当前线程调用此方法,同时当前线程进入TIMED_WAITING状态,但是不释放对象锁,millis后线程会自动苏醒并进入就绪状态。作用是给其他线程执行机会的最佳方式

Thread.yield()  // Thread类的静态方法。一定是当前线程调用此方法,使当前线程放弃获取的CPU时间片,但是不释放锁资源,由运行状态变为就绪状态,让调度程序再次选择线程。作用是让相同优先级的线程轮流执行,但并不保证一定会轮流执行。实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。Thread.yield()不会导致阻塞。该方法与sleep()类似,只是不能由用户指定暂停多长时间。

t.join() / t.join(long millis)  // 在当前线程里,使用其他线程的引用调用join()方法,当前线程进入WAITING / TIMED_WAITING状态,当前线程不会释放已持有的对象锁。等被调用的其它线程执行完毕或者millis时间到,当前线程再进入就绪状态准备执行。

obj.wait() / obj.wait(long timeout)  // 当前线程调用对象的wait()方法,当前线程释放对象锁,进入等待队列。依靠notify() / notifyAll()唤醒;或者timeout时间到了自动幻想

obj.notify()   // 唤醒在此对象监视器上等待的单个线程,选择是任意的。

obj.notifyAll()  // 唤醒在此对象监视器上等待的所有线程。

posted on 2018-09-18 11:12  0820LL  阅读(242)  评论(0编辑  收藏  举报

导航