1.线程状态图

当我们new 一个Thread的时候,就是告诉CPU我们创建一个新的线程,这个时候只是创建过程。当我们开始为创建的线程调用start()的方法时,我们的线程就进入的就绪状态。所以我们一般不直接开始调用run的方法。就绪状态好了之后,就会反选run的方法。如果出现某种特殊的情况,那么线程可以还会进入就绪状态。例如,某个线程的优先级比较高的时候,需要它先使用。当然,在线程执行的时候,可能出现者线程进入休眠状、wait()的时候,使用线程挂起,那么线程处于阻塞状态。只有线程运行结束后,再也得不到CPU时间,它就结束了。如图所示。

2. 线程状态

我们继续上面的学习,这里我们可能说的线程状态词与上图不一样,我们用专业词来解说。

1)        新建(New):当线程被创建时,它会短暂地处于这种状态。此时它已经分配了必需的系统资源,并执行了初始化。此刻线程已经有资格获得CPU时间了,之后调度器将把这个线程转变为可运行状态或阻塞状态。

2)        就绪(Runnable):在这种状态下,只要调度器把时间片分配给线程,线程就可以运行。也就是说,在任意时刻可以运行也可以不运行。只需调度器能分配时间片给线程,它就可以运行;这不同于死亡和阻塞。

3)        阻塞(Blocked):线程能够运行,但有某个条件阻止它运行。线程处于阻塞状态时,调度器将忽略线程,不会分配给线程任何CPU时间。直到线程重新进入就绪状态,它才有可能执行操作。

4)        死亡(Dead):处于死亡或终止状态的线程将不再是可调度的。当线程再也不会得到CPU时间,它的任务已结束,或不再是可运行的。任务死亡的通常方式是从run()方法返回,但是任务的线程还可以被中断,你将要看到这一点。

3.进入阻塞状态

一个任务进入阻塞状态,可能的如下原因:

1)        通过调用sleep(milliseconds)使任务进入休眠状态,在这种情况下,任务在指定的时间内不会运行。

2)        你通过调用wait()使线程挡挂起。走到线程得到了notify()或notifyAll()消息,线程才会进入就绪状态。

3)        任务在等待某个输入、输出完成。

4)        任务试图在某个对象上调用其同步控制方法,但是对象锁不可用,因为另一个任务已经获取了这个锁。

4.线程控制基本方法

5. sleep方法使用

下面的例子,我们使用了Thread.sleep()的方法,说明当前的主线程(main)将会休眠多久时间,所以主线程 在休眠期间thread.interrupt()是不会被执行的,但是另外的新线程依然会在运行。当主线程醒来之后,就会执行interruput()的方法。这个方法是在Thread类的包中,方法将设置线程的中断状态。如果一个线程已经阻塞,或者试图执行一个阻塞操作,那么设置这个线程的中断状态将抛出InterruptedException.

package com.owen.thread;import java.util.Date;/*** 子线程在运行时,主线程休眠10秒* * @author OwenWilliam 2016-7-21* @since* @version v1.0.0**/
public class TestInterrupt
{public static void main(String[] args){MyThread thread = new MyThread();thread.start();try{// 主线程休眠10秒Thread.sleep(10000);} catch (InterruptedException e){}// 断掉子线程,不要使用stop()方法,stop()会立刻停止,不会将flag设置为falsethread.interrupt();}}/*** 创建个线程,每隔一秒就打印出时间* * @author OwenWilliam 2016-7-21* @since* @version v1.0.0**/
class MyThread extends Thread
{public void run(){boolean flag = true;while (flag){System.out.println("====" + new Date() + "====");try{// 休眠1秒sleep(1000);} catch (InterruptedException e){flag = false;return;}}}
}

6. join方法使用

一个线程可以在其它线程之上调用join()方法,其效果是等待一段时间直到第二个线程结束才继续执行。如果某个线程在另一个线程t上调用t.join(),此线程被挂起,直到目标线程t结束才恢复(t.isAlive()返回为假)。届可以在调用join()时带上一个超时参数(单位可以是毫秒和纳秒),这样如果目标线程在这段时间到期还没有结束的话,join()方法总能返回。

下面的例子就是实现将t1的线程合并到主线程上,原先是有两条线程,现在join()之后变成了只有一条主线程子。所以要等t1.start()的方法执行好了之后才可以执行后面的线程。

package com.owen.thread;/*** 使用join()的方法,将MyThread2的线程合并到主线程中, 这个时候就相当于调用方法了,* 等待一个线程运行好了才可以运行下一个线程* * @author OwenWilliam 2016-7-21* @since* @version v1.0.0**/
public class TestJoin
{public static void main(String[] args){MyThread2 t1 = new MyThread2("t1");t1.start();try{// 合并线程到主线程t1.join();} catch (InterruptedException e){}
System.out.println("thread isAlive:" + t1.isAlive());for (int i = 1; i <= 10; i++){System.out.println("i am main thread");}}}/*** 创建线程,每隔1秒打印一行信息* * @author OwenWilliam 2016-7-21* @since* @version v1.0.0**/
class MyThread2 extends Thread
{MyThread2(String s){super(s);}public void run(){for (int i = 1; i <= 10; i++){System.out.println("i am " + getName());try{sleep(1000);} catch (InterruptedException e){return;}}}
}

7.yield方法

在下面的例子中,我们使用了静态方法Thread.yield()调用是对线程调度器(Java线程机制的一部分,可以将CPU从一个线程转移到另一个线程)的一种建议,它声明:”我已经执行完生命周期中最重要的部分了,此刻正是切换给其他任务执行一段时间的大好时机。”

package com.owen.thread;/*** 测试Thread线程的yield的方法* * @author OwenWilliam 2016-7-21* @since* @version v1.0.0**/
public class TestYield
{public static void main(String[] args){MyThread3 t1 = new MyThread3("t1");MyThread3 t2 = new MyThread3("t2");t1.start();t2.start();}}/*** 创建线程,当i的值为10的倍数时,那么就让出线程,给其它线程执行一会儿,注意是一会儿* * @author OwenWilliam 2016-7-21* @since* @version v1.0.0**/
class MyThread3 extends Thread
{MyThread3(String s){super(s);}public void run(){for (int i = 1; i <= 100; i++){System.out.println(getName() + ": " + i);if (i % 10 == 0){// 让出线程一会儿yield();}}}
}

8.线程的优先级别

线程持优先级将线程的重要性传递给了调度器。尽管CPU处理现有线程集的顺序是不确定的,但是调度器将倾向于让优先权最高的线程先执行。然而,这并不意味着优先权较低的线程将得不到执行(也就是说,优先权不会导致死锁)。优先级较低的线程仅仅是执行频率较低。

1)        Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调度哪个线程来执行。

2)        线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级是5.

a)        Thread.MIN_PRIORITY = 1

b)        Thread.MAX_PRIOROTY = 10

c)        Thread.NORM_PRIORITY = 5

3)        使用下述方法获得或设置线程对象的优先级。

a)        int getPriority();

b)        void setPriority(intnewPriority);

下面有例子中,我们分别在主线程上分出两条新的线程,它们分别 是t1和t2,所以正常情况下它们执行时间是相同的,也就是CPU会执行t1一会儿然后再执行t2一会儿,只是时间很快你感受不到,所以感觉就是多线程在执行。当我们在t1上加了优先级高之后,那么t1执行的时间就相对于t2要长一点了。

package com.owen.thread;/*** 测试线程的优先级使用* @author OwenWilliam 2016-7-21* @since* @version v1.0.0**/
public class TestPriority
{public static void main(String[] args){Thread t1 = new Thread(new T1());Thread t2 = new Thread(new T2());//t1线程的优先级加3t1.setPriority(Thread.NORM_PRIORITY + 3);t1.start();t2.start();}}/*** 线程T1输出数据* @author OwenWilliam 2016-7-21* @since* @version v1.0.0**/
class T1 implements Runnable
{@Overridepublic void run(){for (int i = 0; i < 1000; i++){System.out.println("T1:" + i);}}}/*** 线程T2的输出数据* @author OwenWilliam 2016-7-21* @since* @version v1.0.0**/
class T2 implements Runnable
{@Overridepublic void run(){for (int i = 0; i < 1000; i++){System.out.println("T2----" + i);}}}

Java线程状态转换相关推荐

  1. java线程切换 notify_浅谈 Java线程状态转换及控制

    作者:城北有个混子 出自:博客园 1.线程的状态(系统层面) 一个线程被创建后就进入了线程的生命周期.在线程的生命周期中,共包括新建(New).就绪(Runnable).运行(Running).阻塞( ...

  2. 【图解】透彻Java线程状态转换

    大家好,我是阿星,好久不见,欢迎来到Java并发编程系列番外篇线程状态转换,内容通俗易懂,请放心食用. 线程状态 先来个开场四连问 Java线程状态有几个? Java线程状态是如何转换? Java线程 ...

  3. java线程主要状态及转换_Java线程状态转换及控制

    线程的状态(系统层面) 一个线程被创建后就进入了线程的生命周期.在线程的生命周期中,共包括新建(New).就绪(Runnable).运行(Running).阻塞(Blocked)和死亡(Dead)这五 ...

  4. JAVA线程状态的10种转换

    JAVA线程状态转换 参考视频:https://www.bilibili.com/video/BV16J411h7Rd 后续将继续补充,同时完善. 情况1NEW–>RUNNABLE ​ 当调用t ...

  5. 【Java多线程】Java线程状态及转换方法详解

    文章目录 1. 现代操作系统中的线程状态及转换(5种) 2. Java 线程状态(6种) 2.1 NEW 创建 2.2 RUNNABLE 运行 2.3 BLOCKED 阻塞 2.4 WAITING 等 ...

  6. java 线程状态_关于JAVA线程状态

    最近在复习java基础知识,在看到java多线程知识的时候偶然搜到一篇csdn上的博客. 这篇博客上弄了一张描述java线程状态转换的图,如下 看到的第一眼直觉上告诉这图我哪里不太对,于是我就去了的相 ...

  7. java 线程状态_JAVA线程漫谈:线程状态与状态转换解析

    线程使用方式 JDK线程的顶层抽象是Runnable接口,本质上,线程相关的类都是基于Runnable和Thread实现类实现. JDK API级别有不同的创建线程的方式,但本质是还是基于Runnab ...

  8. Java线程状态及转换

    推荐:Java并发编程汇总 Java线程状态及转换 原文地址 Java线程状态和关闭线程的正确姿势 正文 Java中的线程有六种状态,使用Thread类中的枚举类来实现,如下,我对每个状态都进行了一定 ...

  9. Java并发知识梳理(上):并发优缺点,线程状态转换,Java内存模型,Synchronized,Volatile,final,并发三特性,Lock与AQS,ReetrandLock

    努力的意义,就是,在以后的日子里,放眼望去全是自己喜欢的人和事! 整个系列文章为Java并发专题,一是自己的兴趣,二是,这部分在实际理解上很有难度,另外在面试过程中也是经常被问到.所以在学习过程中,记 ...

  10. 面试必备,Java线程状态之细节回顾

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 来源:https://dwz.cn/vYqjShos Java线程有6种状态 在某个给定时间点 ...

最新文章

  1. python 删除字符串中的所有相邻的重复项
  2. linux 内核dmesg,linux內核調試kmsg,dmesg
  3. csrf攻击 java_java使用jsp servlet来防止csrf 攻击的实现方法
  4. [003]容器和动态数组的使用
  5. 黑马程序员_java基础笔记(06)...集合
  6. Android零基础入门第31节:几乎不用但要了解的AbsoluteLayout绝对布局
  7. Python实战从入门到精通第十三讲——返回多个值的函数
  8. 中国临床诊断自动化行业市场供需与战略研究报告
  9. 洛谷 P1875 佳佳的魔法药水
  10. 熵权法 —— matlab
  11. OTO电子商务商业模式探析
  12. html表格中如何画单元格中对角线
  13. Nik Collection 5
  14. 单片机简易开发板怎么设计,我来告诉你
  15. Corolado软件峰会关于Geronimo的介绍
  16. Qt音视频开发04-保存音频文件(pcm/wav/aac)
  17. 常用的Linux命令.cmd
  18. 往事如风,往事如烟,岁月如歌
  19. 为什么学人工智能专业后悔死了?
  20. 关于Linux的开元及命令介绍

热门文章

  1. shadow Dom(shadowRoot) 访问
  2. SharePoint 2013创建WCF REST Service
  3. Eric的日期选择下拉列表小控件
  4. 2022 AAAI 多模态/情感分析/命名实体识别/(信息抽取)关系抽取/知识图谱(知识蒸馏)/阅读理解 论文一览表
  5. Linux之软件安装rpm、yum/dnf、源码(安装)
  6. shell脚本练习实例
  7. ​老男孩教育每日一题-第73天 -基础命令点:可恶的^C
  8. fio 磁盘IO性能测试
  9. 解决Macbook网络连接成功但是图标一直显示正在查找网络问题
  10. 如何迅速的找到合适的开发者?