1、New新状态:线程对象已经创建,还没有在其上调用start()方法。
2、Runnable可运行状态:当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态。当start()方法调用时,线程首先进入可运行状态。在线程运行之后或者从阻塞、等待或睡眠状态回来后,也返回到可运行状态。
3、Running运行状态:线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。
4、Wait/Blocked/Sleep等待/阻塞/睡眠状态:这是线程有资格运行时它所处的状态。实际上这个三状态组合为一种,其共同点是:线程仍旧是活的,但是当前没有条件运行。换句话说,它是可运行的,但是如果某件事件出现,他可能返回到可运行状态。
5、Dead死亡态:当线程的run()方法完成时就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。 如果在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
Thread.yield()方法作用是:暂停当前正在执行的线程对象,并执行其他线程。
yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。
运行状态比较复杂:
第一:线程如果执行run() main()方法结束后,完成逻辑,线程就进入Terminated
第二:当线程调用sleep()或者join()方法就会进入Blocked状态,但是要注意的是阻塞的线程是不释放当前所占有的系统资源,当sleep()结束或者join()等待其他线程来到,当前线程则进入Runnable状态等待JVM分配资源。
第三:当线程进入Runnable状态,但是还没有开始运行的时候,此时发现需要的资源处于同步状态synchronized,这个时候线程将会进入Time waiting,JVM会使用队列对这些线程进行控制,既先进行Time waiting的线程会先得到JVM资源进行执行进入Waiting
第四:如果处于Runnable的线程调用yield()让出JVM资源,那么就会进入New状态和其他New状态线程进行竞争重新进入Runnable
第五:如果当前线程调用wait()方法,则当前线程进入Time waiting但是这个时候当前线程会释放所占有的JVM资源,进入这个状态过后是不能自动唤醒的,必须调用notify()或者notifyAll()方法,线程进入Waiting。
Wait pool 等待池
Lock pool 锁池
结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。
Jstack的输出中,Java线程状态主要是以下几种:
- RUNNABLE 线程运行中或I/O等待
- BLOCKED 线程在等待monitor锁(synchronized关键字)这里要注意的是只有synchronized这种方式的锁(monitor锁)才会让线程出现BLOCKED状态,等待ReentrantLock则不会。
- TIMED_WAITING 线程在等待唤醒,但设置了时限 lock.wait(30 * 1000);
- WAITING 线程在无限等待唤醒 lock.wait();必须等待lock.notify()或lock.notifyAll()或接收到interrupt信号才能退出等待状态。同理,ReentrantLock.lock()的无参方法调用,也会使线程状态变成WAITING。
1.sleep()方法
在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。不推荐使用。
sleep()使当前线程进入阻塞状态,在指定时间内不会执行。
2.wait()方法
在其他线程调用对象的notify或notifyAll方法前,导致当前线程等待。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。
http://blog.csdn.net/xionghan01/article/details/52840358
http://blog.csdn.net/tanga842428/article/details/52572976