java多线程之线程状态
来源:互联网 发布:雪碧放了几天 知乎 编辑:程序博客网 时间:2024/05/05 18:59
转载请注明出处
http://blog.csdn.net/pony_maggie/article/details/42886735
作者:小马
新建状态(New)
新创建了一个线程对象,但是还没有start。就绪状态(Runnable)
线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。也是通常线程的状态。
运行状态(Running)
就绪状态的线程获取了CPU,执行程序代码。
死亡状态(Dead)
线程执行完了,比如run方法结束。或者因异常退出了run()方法。另外还有一个destroy方法,一般不建议使用。
阻塞状态(Blocked)
阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的原因有以下几种:
1 调用sleep(milliseconds)方法,JVM会把该线程置为阻塞状态,直到指定的时间结束。
2 调用了suspend方法变为阻塞状态,这种只能通过调用resume方法恢复。这种方式已经不用了。
3 运行的线程执行wait()方法, JVM会把该线程放入等待池中直到线程得到notify或者notifyAll的消息。
4 线程等待I/O处理完毕。
5 运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用。
下面就分别对这5种情况给出demo示例。
首先是两个通用的类,一个是Blockable,它是后面所有要创建线程类的基类,它封装了一个文本框的成员,这个文本框显示它的一个整型成员的值。类的定义如下:
class Blockable extends Thread{private Peeker peeker;protected JTextField state = new JTextField(30);protected int i;public Blockable(Container c){c.add(state);peeker = new Peeker(this, c);}public synchronized int read() {return i;}protected synchronized void update(){state.setText(getClass().getName() + " state:i = " +i);}public void stopPeeker(){peeker.terminate();}}
Blockable还有一个监视器成员,Peeker,它也是一个线程类,它的功能是监视Blockable所有线程实例中整型成员的值,类的定义如下:
class Peeker extends Thread{private Blockable b;private int session;private JTextField status = new JTextField(30);private boolean stop = false;public Peeker(Blockable b, Container c){c.add(status);this.b = b;start();}public void terminate(){stop = true;}public void run(){while(!stop){status.setText(b.getClass().getName()+" Peeker " + (++session) +"; value = " + b.read());try {sleep(100);} catch (InterruptedException e) {System.err.println("Interrupted");}}}}
先看看sleep的方式,示例创建了两个类进行比较,分别为Sleeper1和Sleeper2,这两个类的唯一区别就在于,run函数里,synchronized修饰的位置,
class Sleeper1 extends Blockable{public Sleeper1(Container c) {super(c);}public synchronized void run(){while(true){i++;update();try {sleep(1000);} catch (InterruptedException e) {System.err.println("Interrupted");}}}}class Sleeper2 extends Blockable{public Sleeper2(Container c) {super(c);}public void run(){while(true){change();try {sleep(1000);} catch (InterruptedException e) {System.err.println("Interrupted");}}}public synchronized void change(){i++;update();}}
先运行看看效果:
最上面两个框是Sleeper1和它对应的监视器Peeker, 然后是Sleeper2和它的监视器。
先来分析Sleeper1, 程序一启动时,监视器线程就启动了,点击start后,Sleeper1的实例线程也开始运行,并能获得执行的机会,但是一旦它获得执行机会(执行run),它就拥有了对象的锁并且不会释放(synchronized加到了整个run上,而run里又有个无限循环。),因为Peeker是这个对象的成员,所以就阻塞了。
所以看到程序的运行效果,Peeker的计数器停止了。Sleeper2没有把整个run置为synchronized,所以不影响Peeker的执行。
总结,
两个Sleeper线程都向我们展示了通过Sleep函数让自己进入睡眠状态,从而其它线程有机会获得执行的机会。当然,synchronized可能会影响结果,这个要注意。
0 0
- java多线程之线程状态
- Java多线程之线程状态
- java多线程之线程状态
- java多线程之线程状态(2)
- java多线程之线程状态(3)
- java 多线程之线程的状态
- Java多线程之线程状态转换
- (14)Java多线程之线程状态
- java多线程之线程运行状态
- Java多线程之线程状态案例
- 二.java多线程之线程状态转换
- Java多线程:线程状态
- java多线程-线程状态
- Java多线程:线程状态
- Java多线程:线程状态
- Java多线程:线程状态
- Java多线程:线程状态
- Java多线程:线程状态
- 对C++中动态内存分配的认识
- Linux静态IP设置
- 论 反射机制 二
- 近段时间android错误总结
- VC点击按键弹出文件路径选择对话框
- java多线程之线程状态
- HDU 1047 -- Integer Inquiry(Java)
- 字符串的复制函数,用my_strcpy(char *s, const char *t)
- JavaWeb:报错信息The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- 两栈共享空间
- linux下软件编译与安装
- 手机键盘
- NPC头上的血条与名字的设置
- Perl Tk grid 布局