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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 脚受伤后肿了怎么办 摔到了腿受伤了怎么办 骑车摔倒了肿了怎么办 生活大冒险老婆失踪了怎么办 手机qq图裂了怎么办 qq发的图裂了怎么办 抖音账号搬运多怎么办 别人搜不到我QQ怎么办 qq号被限制解封怎么办 买的桌子会晃怎么办 车子座椅皮坏了怎么办 裤子被椅子刮了怎么办 脚麻了被别人动怎么办 毛孔又粗又黑怎么办 手臂睡觉压麻了怎么办 睡觉压的胳膊麻怎么办 摔跤摔到腰肿了怎么办 牛奶喝多了拉稀怎么办 doc文档下载是乱码怎么办 家人被教练技术骗了怎么办 十个月宝宝不爱喝水怎么办 离婚后孩子找爸爸怎么办 离婚后孩子要找爸爸怎么办 断奶期间胸涨的难受怎么办 断奶胸涨的很疼怎么办 过了麦季身上老痒怎么办 过麦时候皮肤痒怎么办 颈部起红疙瘩痒怎么办 脚底痒身上痒该怎么办 生完孩子屁股疼怎么办 pr打开工程文件无响应怎么办 娃娃和老师有隔阂了怎么办 大人字写得不好怎么办 不会写好看的字怎么办 无限量流量限速了怎么办 长期化妆后皮肤变黄怎么办 手机密码忘记了打不开怎么办 手机解压包不知道密码怎么办 手机屏图标没了怎么办 b站页面卡顿怎么办 被全景视觉骗了怎么办?