java 线程 状态 图_Java提高——多线程(一)状态图

操作系统中的进程和线程的概念

进程是指一个内存运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程,比如windows下的一个运行的应用程序.exe就是一个进程。

线程是指进程中的一个执行流,一个进程可以运行多个线程。如java.exe就可以运行很多个线程。线程总是属于某个进程,进程中的多个线程共享进程中的内存。

操作系统中可以同时执行多个任务,每个任务就是进程;进程可以同时执行多个任务,每个任务就是线程。

线程的状态

85e71d9c51e86db3b661896ce2a06815.png

1、新建(new):线程对象被创建后就进入了新建状态。如:Thread thread = new Thread();

2、就绪状态(Runnable):也被称为“可执行状态”。线程对象被创建后,其他线程调用了该对象的start()方法,从而启动该线程。如:thread.start(); 处于就绪状态的线程随时可能被CPU调度执行。

3、运行状态(Running):线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。

4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权限,暂时停止运行。直到线程进入就绪状态,才有机会进入运行状态。阻塞的三种情况:

1)等待阻塞:通过调用线程的wait()方法,让线程等待某工作的完成。

2)同步阻塞:线程在获取synchronized同步锁失败(因为锁被其他线程占用),它会进入同步阻塞状态。

3)其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或超时、或者I/O处理完毕时,线程重新转入就绪状态。

5、死亡状态(Dead):线程执行完了或因异常退出了run()方法,该线程结束生命周期。

常用的实现多线程的方式

1、继承Thread类publicclassThread implementsRunnable {、、、、、}

由Thread的源码可以看出,Thread是实现了Runnable接口。

2、实现Runnable接口

publicinterfaceRunnable {

public abstract voidrun();}

Runnable接口只有一个run()方法

————————————————————————————————————————————————

Thread和Runnable都是是实现实现多线程的方式。不同的是Thread是类,Runnable是接口——Thread本身实现了Runnable接口,一个类只能有一个父类,但是却可以是实现多个接口,因此Runnable具有更好的扩展性。

Thread实现多线程public classMyThread extendsThread {

private inti;@Override/** 重写run方法*/public voidrun(){

for(inti = 0;i < 50;i++) {

/*** 当继承Thread类可以直接用this获取当前线程* 用getName()获取当前线程的名字*/System.out.println(this.getName()+"-"+i);}

}

public static voidmain(String[] args) {

for(inti = 0;i < 100;i++) {

//通过Thread.currentThread()获取当前线程System.out.println(Thread.currentThread().getName()+" "+i);if(i==20){

//创建并启动第一个线程newMyThread().start();//创建并启动第二个线程newMyThread().start();}

}

}

}

Runnable实现多线程public classMyRunnable implementsRunnable {

private inti;@Overridepublic voidrun() {

for(inti = 0;i < 50;i++) {

/**当线程类实现Runnable接口的时候,获取当前线程只能用Thread.currentThread()*/System.out.println(Thread.currentThread().getName()+" "+i);}

}

public static voidmain(String[] args) {

for(inti = 0;i < 100;i++) {

// System.out.println(Thread.currentThread().getName()+" "+i);if(i==20){

MyRunnable mr = newMyRunnable();//通过new Start()方法创建新线程newThread(mr,"线程1").start();newThread(mr,"线程2").start();}

}

}

}

关于线程中的start()和run()

启动线程使用start(),而不是run()!

4ab52dfa8b9eabd8229a14f581e3f376.png

在执行start()方法之前,只是有一个Thread对象,还没一个真正的线程。(分配内存,初始化成员变量)

——>start()之后,线程状态从新状态到可执行状态。(调用栈和计数器,线程没运行,只是可以运行)

——>当线程获得执行机会时,其目标run()方法将运行。

start():他的作用是启动一个新线程,新线程会调用相应的run()方法。start()不能被重复调用。

run():和普通成员的方法一样可以被重复调用。单独调用run()会在当前线程中执行run(),而不会启动新的线程。

public classMyThread extendsThread {@Override/** 重写run方法*/public voidrun(){

}

}

MyThread myThread = new MyThread();

如:myThread.start()会启动一个新的线程,然后在新线程中执行run()方法。

myThread.run()会直接在当前线程中运行run()方法,不会启动一个线程。

start方法源码:public synchronized voidstart() {

/**

*如果线程不是就绪状态就抛出异常*/if(threadStatus!= 0)

throw newIllegalThreadStateException();/* 将线程添加到group当中 */group.add(this);booleanstarted = false;try{

start0();//通过start0启动线程started = true;//设置started标记} finally{

try{

if(!started) {

group.threadStartFailed(this);}

} catch(Throwable ignore) {

/* do nothing. If start0 threw a Throwable thenit will be passed up the call stack */}

}

}

run方法源码:public voidrun() {

if(target!= null) {

target.run();}

}

其中target是Runnable对象, 直接调用Thread线程中Runnable接口中run方法,不会新建一个线程。

当线程获得CPU,开始执行run()方法的线程执行体,则该线程处于运行状态。

关于阻塞

e266c4317886029c7858c6f8bb4841b1.png

进入阻塞的情况:解除上面阻塞情况:

1、线程调用sleep()方法主动释放占用的处理器资源

2、调用了一个阻塞式的IO方法,在方法返回前线程被阻塞

3、线程获得了一个同步监视器(Syschronized),但该监视器正被其他线程持有

4、线程在等待某个通知(notify)

5、程序调用了线程的resume()方法将线程挂起。但是该方法容易发生死锁,所以尽量避免使用1、调用sleep()方法经过了指定的时间

2、线程调用的IO阻塞方法已经返回

3、线程成功的获得了试图取得的同步监视器

4、线程正在等待某个通知时,其他线程发出了一个通知

5、处于挂起的线程被调用了resume()恢复方法。

线程从阻塞状态只能进入就绪状态,无法进入运行状态,而从就绪到运行不受程序控制,由系统线程调度决定。

获得资源进入运行状态,失去资源进入就绪状态。

线程死亡

e6ba587fd6b1738b78ba8908964a7409.png

线程死亡会以一下三种状况结束:

—>调用run或call方法执行完成,正常结束

—>线程抛出一个为捕获的Exception或Error

—>直接调用stop()方法来结束该线程——容易导致死锁,不推荐。

不要试图对死亡的线程使用start()方法,将会抛出异常,并不会重启死亡的异常!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/459793.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UITableView 重用cell方法edequeueReusableCellWithIdentifier,出现错误

UITableView 使用重用cell方法edequeueReusableCellWithIdentifier&#xff0c;出现错误&#xff1a;*** Terminating app due to uncaught exception NSInternalInconsistencyException, reason: unable to dequeue a cell with identifier cell3 - must register a nib or a …

学习ecshop 教程网址

http://www.chinab4c.com&#xff08;中国B4C电子商务&#xff09;转载于:https://www.cnblogs.com/ymj0906/p/4175681.html

幽幽的灵光射不出你想要的疯狂

秋天到了&#xff0c;忧伤便无处可逃&#xff0c;秋天的忧伤的气息&#xff0c;就像一个妖艳的美女躺在你的身边&#xff0c;让你热血沸腾&#xff0c;冲动无比&#xff0c;而又悲喜交加&#xff0c;忧愁满地。如果不信&#xff0c;你可以试试。分享一首去年的诗歌&#xff0c;…

java 复杂 sql_复杂的SQL条件

概述什么是 Nutz.Dao 中的复杂SQL条件对于 Nutz.Dao 来说&#xff0c;它本质上就是将你的 Java 对象转化成 SQL&#xff0c;然后交给 JDBC 去执行。而 SQL 中&#xff0c;当执行数据删除和查询操作时&#xff0c;最常用的就是 WHERE 关键字。WHERE 关键字后面的就是所谓的复杂查…

找规律

找规律填写NN方阵。如N8时, 其方阵为: 1 1 1 1 1 1 1 11 2 2 2 2 2 2 11 2 3 3 3 3 2 11 2 3 4 4 3 2 11 2 3 4 4 3 2 11 2 3 3 3 3 2 11 2 2 2 2 2 2 11 1 1 1 1 1 1 1 上代码&#xff1a; 1 #include <stdio.h&g…

arm qt5 iconv 问题

2019独角兽企业重金招聘Python工程师标准>>> 问题 3&#xff1a;./system/rootlib/helloworld -qws &#xff0c;程序运行起来&#xff0c;仍报错 QIconvCodec::convertFromUnicode: using Latin-1 for conversion, iconv_open failed …

android java 调试快捷键_Android Studio 代码页跳界面 /java和XML快速切换技巧

从csdn博客搬家过来&#xff0c;请多关照&#xff01;之前一直在csdn博客,也写了不少关于java的文章,主要是学习java上的一些问题.想通过这种方式来加深对问题的认知,同时也可以帮助到志同道合的人,一起在编程的道路上共进,共勉.fancybox的配置项Fancybox的API和配置选项说明 属…

设计模式之Builder (创建者模式)的一些个人理解(转)

对于Builder模式很简单&#xff0c;但是一直想不明白为什么要这么设计&#xff0c;为什么要向builder要Product而不是向知道建造过程的Director要。刚才google到一篇文章&#xff0c;总算清楚了。在这里转贴一下这位richardluo的比喻。简单地说&#xff0c;就好象我要一座房子住…

python-多继承

python中的多继承python和C一样&#xff0c;支持多继承。概念虽然容易&#xff0c;但是困难的工作是如果子类调用一个自身没有定义的属性&#xff0c;它是按照何种顺序去到父类寻找呢&#xff0c;尤其是众多父类中有多个都包含该同名属性。class P1 #(object): def foo(self…

java父子表_Java编程:将具有父子关系的数据库表数据转换为树形结构,支持无限层级...

在平时的开发工作中&#xff0c;经常遇到这样一个场景&#xff0c;在数据库中存储了具有父子关系的数据&#xff0c;需要将这些数据以树形结构的形式在界面上进行展示。本文的目的是提供了一个通用的编程模型&#xff0c;解决将具有父子关系的数据转换成树形结构的问题。如有不…

[转]用Whois获得电信运营商的IP地址是如何分配的?

[转]用Whois获得电信运营商的IP地址是如何分配的? Linux下获得一些中国电信运营商的IP地址分配情况: APNIC是管理亚太地区IP地址分配的机构&#xff0c;它有着丰富准确的IP地址分配库&#xff0c;同时这些信息也是对外公开的&#xff0c;并提供了一个查询工具&#xff0c;下面…

BZOJ 2301 Problem b(莫比乌斯反演+分块优化)

题目链接&#xff1a;http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id37166 题意&#xff1a;对于给出的n个询问&#xff0c;每次求有多少个数对(x,y)&#xff0c;满足a≤x≤b&#xff0c;c≤y≤d&#xff0c;且gcd(x,y) k&#xff0c;gcd(x,y)函数为x和y的最大…

java importgeopoint_如何在地图上显示更多点(GeoPoint)?

目前&#xff0c;我能够在代码中显示第一个点(pointStatie)的一点&#xff0c;但我希望显示两个点。我想要显示我所在的位置&#xff0c;以及我从另一个班级通过坐标的另一点。我目前的代码是&#xff1a;package aexp.elistcbox;import android.os.Bundle;import android.prov…

Java实现串口通信的小样例

用Java实现串口通信&#xff08;windows系统下&#xff09;&#xff0c;须要用到sun提供的串口包 javacomm20-win32.zip。当中要用到三个文件&#xff0c;配置例如以下&#xff1a; 1.comm.jar放置到 JAVA_HOME/jre/lib/ext; 2.win32com.dll放置到 JAVA_HOME/bin; 3.javax.comm…

庆祝教师节,李宁老师课程优惠劵疯抢中、会员卡优惠中,先到先得

李宁老师会员卡&#xff08;9-10至9-14&#xff09;大优惠&#xff1a;http://edu.51cto.com/member/id-12_1.html优惠劵只能购买李宁老师的视频课程&#xff1a;http://edu.51cto.com/member/id-12_1.html 优惠劵有效期&#xff1a;2015-9-10 至 2015-9-14 购买规则&#xf…

java mset_Java 反射机制(包括组成、结构、示例说明等内容)

第1部分 Java 反射机制介绍Java 反射机制。通俗来讲呢&#xff0c;就是在运行状态中&#xff0c;我们可以根据“类的部分已经的信息”来还原“类的全部的信息”。这里“类的部分已经的信息”&#xff0c;可以是“类名”或“类的对象”等信息。“类的全部信息”就是指“类的属性…

XML序列化和反序列化 以及相关类的写法

类的写法&#xff1a; 省网办数据对接中运用到 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Serialization;namespace SWBExchange.Common.Entities {public class Body{[XmlElement(ElementName "BasicIn…

python-main

当你打开一个.py文件时,经常会在代码的最下面看到if __name__ __main__:,现在就来介 绍一下它的作用.模块是对象&#xff0c;并且所有的模块都有一个内置属性 __name__。一个模块的 __name__ 的值取决于您如何应用模块。如果 import 一个模块&#xff0c;那么模块__name__ 的值…

自己动手,实现一种类似ListT的数据结构(二)

前言&#xff1a; 首先&#xff0c;小匹夫要祝各位看官圣诞快乐&#xff0c;新年愉快&#xff5e;。上一篇文章《自己动手&#xff0c;实现一种类似List<T>的数据结构(一&#xff09;》 介绍了一下不依靠List<T>实现的各种接口&#xff0c;仿造一个轻量级数据结构的…

java spring jdbc_Spring与JDBC支持

JDBC是一种标准Java编程接口(JAVA API)&#xff0c;可以将Java编程语言与广泛数据库进行连接。JDBC API库包含下面提到的每个任务&#xff0c;都是与数据库相关的常用用法。数据库的连接创建sql语句执行或提交sql语句查看或修改查询到的记录从根本上说&#xff0c;JDBC是一种规…