本篇文章给大家谈谈java线程状态转移图,以及线程状态流转图对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
今天给各位分享java线程状态转移图的知识,其中也会对线程状态流转图进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
线程的状态及状态间的转换图
一、线程的概念
一般来说,
java线程状态转移图我们把正在计算机中执行的程序叫做"进程"(Process) ,而不将其称为程序(Program)。所谓"线程"(Thread),是"进程"中某个单一顺序的控制流。
新兴的操作系统,如Mac,Windows NT,Windows 95等,大多采用多线程的概念,把线程视为基本执行单位。线程也是Java中的相当重要的组成部分之一。
甚至最简单的Applet也是由多个线程来完成的。在Java中,任何一个Applet的paint()和update()方法都是由AWT(Abstract Window Toolkit)绘图与事件处理线程调用的,而Applet 主要的里程碑方法——init(),start(),stop()和destory() ——是由执行该Applet的应用调用的。
单线程的概念没有什么新的地方,真正有趣的是在一个程序中同时使用多个线程来完成不同的任务。某些地方用轻量进程(Lightweig ht Process)来代替线程,线程与真正进程的相似性在于它们都是单一顺序控制流。然而线程被认为轻量是由于它运行于整个程序的上下文内,能使用整个程序共有的资源和程序环境。
作为单一顺序控制流,在运行的程序内线程必须拥有一些资源作为必要的开销。例如,必须有执行堆栈和程序计数器。在线程内执行的代码只在它的上下文中起作用,因此某些地方用"执行上下文"来代替"线程"。
二、线程属性
为
java线程状态转移图了正确有效地使用线程,必须理解线程的各个方面并了解Java 实时系统。必须知道如何提供线程体、线程的生命周期、实时系统如 何调度线程、线程组、什么是幽灵线程(Demo nThread)。
(1)线程体
所有的操作都发生在线程体中,在Java中线程体是从Thread类继承的run()方法,或实现Runnable接口的类中的run()方法。当线程产生并初始化后,实时系统调用它的run()方法。run()方法内的代码实现所产生线程的行为,它是线程的主要部分。
(2)线程状态
附图表示了线程在它的生命周期内的任何时刻所能处的状态以及引起状态改变的方法。这图并不是完整的有限状态图,但基本概括了线程中比较感兴趣和普遍的方面。以下讨论有关线程生命周期以此为据。
●新线程态(New Thread)
产生一个Thread对象就生成一个新线程。当线程处于"新线程"状态时,仅仅是一个空线程对象,它还没有分配到系统资源。因此只能启动或终止它。任何其
java线程状态转移图他操作都会引发异常。
●可运行态(Runnable)
start()方法产生运行线程所必须的资源,调度线程执行,并且调用线程的run()方法。在这时线程处于可运行态。该状态不称为运行态是因为这时的线程并不总是一直占用处理机。特别是对于只有一个处理机的PC而言,任何时刻只能有一个处于可运行态的线程占用处理 机。Java通过调度来实现多线程对处理机的共享。
●非运行态(Not Runnable)
当以下事件发生时,线程进入非运行态。
①suspend()方法被调用;
②sleep()方法被调用;
③线程使用wait()来等待条件变量;
④线程处于I/O等待。
●死亡态(Dead)
当run()方法返回,或别的线程调用stop()方法,线程进入死亡态 。通常Applet使用它的stop()方法来终止它产生的所有线程。
(3)线程优先级
虽然
java线程状态转移图我们说线程是并发运行的。然而事实常常并非如此。正如前面谈到的,当系统中只有一个CPU时,以某种顺序在单CPU情况下执行多线程被称为调度(scheduling)。Java采用的是一种简单、固定的调度法,即固定优先级调度。这种算法是根据处于可运行态线程的相对优先级来实行调度。当线程产生时,它继承原线程的优先级。在需要时可对优先级进行修改。在任何时刻,如果有多条线程等待运行,系统选择优先级最高的可运行线程运行。只有当它停止、自动放弃、或由于某种原因成为非运行态低优先级的线程才能运行。如果两个线程具有相同的优先级,它们将被交替地运行。
Java实时系统的线程调度算法还是强制性的,在任何时刻,如果一个比其他线程优先级都高的线程的状态变为可运行态,实时系统将选择该线程来运行。
(4)幽灵线程
任何一个Java线程都能成为幽灵线程。它是作为运行于同一个进程内的对象和线程的服务提供者。例如,HotJava浏览器有一个称为" 后台图片阅读器"的幽灵线程,它为需要图片的对象和线程从文件系统或网络读入图片。
幽灵线程是应用中典型的独立线程。它为同一应用中的其他对象和线程提供服务。幽灵线程的run()方法一般都是无限循环,等待服务请求。
(5)线程组
每个Java线程都是某个线程组的成员。线程组提供一种机制,使得多个线程集于一个对象内,能对它们实行整体操作。譬如,你能用一个方法调用来启动或挂起组内的所有线程。Java线程组由ThreadGroup类实现。
当线程产生时,可以指定线程组或由实时系统将其放入某个缺省的线程组内。线程只能属于一个线程组,并且当线程产生后不能改变它所属的线程组。
三、多线程程序
对于多线程的好处这就不多说了。但是,它同样也带来了某些新的麻烦。只要在设计程序时特别小心留意,克服这些麻烦并不算太困难。
(1)同步线程
许多线程在执行中必须考虑与其他线程之间共享数据或协调执行状态。这就需要同步机制。在Java中每个对象都有一把锁与之对应。但Java不提供单独的lock和unlock操作。它由高层的结构隐式实现, 来保证操作的对应。(然而,我们注意到Java虚拟机提供单独的monito renter和monitorexit指令来实现lock和unlo
ck操作。)
synchronized语句计算一个对象引用,试图对该对象完成锁操作, 并且在完成锁操作前停止处理。当锁操作完成synchronized语句体得到执行。当语句体执行完毕(无论正常或异常),解锁操作自动完成。作为面向对象的语言,synchronized经常与方法连用。一种比较好的办法是,如果某个变量由一个线程赋值并由别的线程引用或赋值,那么所有对该变量的访问都必须在某个synchromized语句或synchronized方法内。
现在假设一种情况:线程1与线程2都要访问某个数据区,并且要求线程1的访问先于线程2, 则这时仅用synchronized是不能解决问题的。这在Unix或Windows NT中可用Simaphore来实现。而Java并不提供。在Java中提供的是wait()和notify()机制。使用如下:
synchronized method-1(…){ call by thread 1.
‖access data area;
available=true;
notify()
}
synchronized method-2(…){‖call by thread 2.
while(!available)
try{
wait();‖wait for notify().
}catch (Interrupted Exception e){
}
‖access data area
}
其中available是类成员变量,置初值为false。
如果在method-2中检查available为假,则调用wait()。wait()的作用是使线程2进入非运行态,并且解锁。在这种情况下,method-1可以被线程1调用。当执行notify()后。线程2由非运行态转变为可运行态。当method-1调用返回后。线程2可重新对该对象加锁,加锁成功后执行wait()返回后的指令。这种机制也能适用于其他更复杂的情况。
(2)死锁
如果程序中有几个竞争资源的并发线程,那么保证均衡是很重要的。系统均衡是指每个线程在执行过程中都能充分访问有限的资源。系统中没有饿死和死锁的线程。Java并不提供对死锁的检测机制。对大多数的Java程序员来说防止死锁是一种较好的选择。最简单的防止死锁的方法是对竞争的资源引入序号,如果一个线程需要几个资源,那么它必须先得到小序号的资源,再申请大序号的资源。
四、线程和进程的比较
进程是资源分配的基本单位。所有与该进程有关的资源,都被记录在进程控制块PCB中。以表示该进程拥有这些资源或正在使用它们。
另外,进程也是抢占处理机的调度单位,它拥有一个完整的虚拟地址空间。
与进程相对应,线程与资源分配无关,它属于某一个进程,并与进程内的其他线程一起共享进程的资源。
当进程发生调度时,不同的进程拥有不同的虚拟地址空间,而同一进程内的不同线程共享同一地址空间。
线程只由相关堆栈(系统栈或用户栈)寄存器和线程控制表TCB组成。寄存器可被用来存储线程内的局部变量,但不能存储其他线程的相关变量。
发生进程切换与发生线程切换时相比较,进程切换时涉及到有关资源指针的保存以及地址空间的变化等问题;线程切换时,由于同不进程内的线程共享资源和地址 空间,将不涉及资源信息的保存和地址变化问题,从而减少了操作系统的开销时间。而且,进程的调度与切换都是由操作系统内核完成,而线程则既可由操作系统内 核完成,也可由用户程序进行。
五、线程的适用范围
典型的应用
1.服务器中的文件管理或通信控制
2.前后台处理
3.异步处理
六、线程的执行特性
一个线程必须处于如下四种可能的状态之一:
初始态:一个线程调用了new方法之后,并在调用start方法之前的所处状态。在初始态中,可以调用start和stop方法。
Runnable:一旦线程调用了start 方法,线程就转到Runnable 状态,注意,如果线程处于Runnable状态,它也有可能不在运行,这是因为还有优先级和调度问题。
阻塞/ NonRunnable:线程处于阻塞/NonRunnable状态,这是由两种可能性造成的:要么是因挂起而暂停的,要么是由于某些原因而阻塞的,例如包括等待IO请求的完成。 退出:线程转到退出状态,这有两种可能性,要么是run方法执行结束,要么是调用了stop方法。
最后一个概念就是线程的优先级,线程可以设定优先级,高优先级的线程可以安排在低优先级线程之前完成。一个应用程序可以通过使用线程中的方法setPriority(int),来设置线程的优先级大小。
线程有5种基本操作:
派生:线程在进程内派生出来,它即可由进程派生,也可由线程派生。
阻塞(Block):如果一个线程在执行过程中需要等待某个事件发生,则被阻塞。
激活(unblock):如果阻塞线程的事件发生,则该线程被激活并进入就绪队列。
调度(schedule):选择一个就绪线程进入执行状态。
结束(Finish):如果一个线程执行结束,它的寄存器上下文以及堆栈内容等将被释放。
七、线程的分类
线程有两个基本类型:
用户级线程:管理过程全部由用户程序完成,操作系统内核心只对进程进行管理。
系统级线程(核心级线程):由操作系统内核进行管理。操作系统内核给应用程序提供相应的系统调用和应用程序接口API,以使用户程序可以创建、执行、撤消线程。
附:线程举例
1. SUN Solaris 2.3
Solaris支持内核线程、轻权进程和用户线程。一个进程可有大量用户线程;大量用户线程复用少量的轻权进程,轻权进程与内核线程一一对应。
用户级线程在调用核心服务时(如文件读写),需要“捆绑(bound)”在一个LWP上。永久捆绑(一个LWP固定被一个用户级线程占用,该LWP移到LWP池之外)和临时捆绑(从LWP池中临时分配一个未被占用的LWP)。
在调用系统服务时,如果所有LWP已被其他用户级线程所占用(捆绑),则该线程阻塞直到有可用的LWP。
如果LWP执行系统线程时阻塞(如read()调用),则当前捆绑在LWP上的用户级线程也阻塞。
¨ 有关的C库函数
/* 创建用户级线程 */
int thr_create(void *stack_base, size_t stack_size,
void *(*start_routine)(void *), void *arg, long flags,
thread_t *new_thread_id);
其中flags包括:THR_BOUND(永久捆绑), THR_NEW_LWP(创建新LWP放入LWP池),若两者同时指定则创建两个新LWP,一个永久捆绑而另一个放入LWP池。
² 有关的系统调用
/* 在当前进程中创建LWP */
int _lwp_create(ucontext_t *contextp, unsigned long flags,
lwpid_t *new_lwp_id);
/* 构造LWP上下文 */
void _lwp_makecontext(ucontext_t *ucp,
void (*start_routine)( void *), void *arg,
void *private, caddr_t stack_base, size_t stack_size);
/* 注意:没有进行“捆绑”操作的系统调用 */
2. Windows NT
NT线程的上下文包括:寄存器、核心栈、线程环境块和用户栈。
NT线程状态
(1) 就绪状态:进程已获得除处理机外的所需资源,等待执行。
(2) 备用状态:特定处理器的执行对象,系统中每个处理器上只能有一个处于备用状态的线程。
(3) 运行状态:完成描述表切换,线程进入运行状态,直到内核抢先、时间片用完、线程终止或进行等待状态。
(4) 等待状态:线程等待对象句柄,以同步它的执行。等待结束时,根据优先级进入运行、就绪状态。
(5) 转换状态:线程在准备执行而其内核堆栈处于外存时,线程进入转换状态;当其内核堆栈调回内存,线程进入就绪状态。
(6) 终止状态:线程执行完就进入终止状态;如执行体有一指向线程对象的指针,可将线程对象重新初始化,并再次使用。
NT线程的有关API
CreateThread()函数在调用进程的地址空间上创建一个线程,以执行指定的函数;返回值为所创建线程的句柄。
ExitThread()函数用于结束本线程。
SuspendThread()函数用于挂起指定的线程。
ResumeThread()函数递减指定线程的挂起计数,挂起计数为0时,线程恢复执行。
java线程中的几种状态以及相互转换
NEW: 线程创建之后,但是还没有启动(not yet started)。
RUNNABLE: 正在Java虚拟机下跑任务的线程的状态。在RUNNABLE状态下的线程可能会处于等待状态, 因为它正在等待一些系统资源的释放,比如IO
BLOCKED: 阻塞状态,等待锁的释放,比如线程A进入了一个synchronized方法,线程B也想进入这个方法,但是这个方法的锁已经被线程A获取了,这个时候线程B就处于BLOCKED状态
WAITING: 等待状态,处于等待状态的线程是由于执行了3个方法中的任意方法。 1. Object的wait方法,并且没有使用timeout参数; 2. Thread的join方法,没有使用timeout参数 3. LockSupport的park方法。 处于waiting状态的线程会等待另外一个线程处理特殊的行为。 再举个例子,如果一个线程调用了一个对象的wait方法,那么这个线程就会处于waiting状态直到另外一个线程调用这个对象的notify或者notifyAll方法后才会解除这个状态
TIMED_WAITING: 有等待时间的等待状态,比如调用了以下几个方法中的任意方法,并且指定了等待时间,线程就会处于这个状态。 1. Thread.sleep方法 2. Object的wait方法,带有时间 3. Thread.join方法,带有时间 4. LockSupport的parkNanos方法,带有时间 5. LockSupport的parkUntil方法,带有时间
TERMINATED: 线程中止的状态,这个线程已经完整地执行了它的任务
java 线程有哪些状态,这些状态之间是如何转化的
线程在它的生命周期中会处于各种不同的状态:
新建、等待、就绪、运行、阻塞、死亡。
1 新建
用new语句创建的线程对象处于新建状态
java线程状态转移图,此时它和其
java线程状态转移图他java对象一样,仅被分配了内存。
2等待
当线程在new之后,并且在调用start方法前,线程处于等待状态。
3 就绪
当一个线程对象创建后,其他线程调用它的start()方法,该线程就进入就绪状态。处于这个状态的线程位于Java虚拟机的可运行池中,等待cpu的使用权。
4 运行状态
处于这个状态的线程占用CPU,执行程序代码。在并发运行环境中,如果计算机只有一个CPU,那么任何时刻只会有一个线程处于这个状态。
只有处于就绪状态的线程才有机会转到运行状态。
5 阻塞状态
阻塞状态是指线程因为某些原因放弃CPU,暂时停止运行。当线程处于阻塞状态时,Java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,它才会有机会获得运行状态。
6 死亡状态
当线程执行完run()方法中的代码,或者遇到了未捕获的异常,就会退出run()方法,此时就进入死亡状态,该线程结束生命周期。
由于java线程调度不是分时的,如果程序希望干预java虚拟机对线程的调度过程,从而明确地让一个线程给另外一个线程运行的机会,可以采用以下的方法
1 调整各个线程的优先级
2 让处于运行状态的线程调用Thread.sleep(long time)方法 放弃CPU 进入阻塞状态。
sleep方法可能抛出InterruptedException
线程休眠后只能在指定的时间后使线程处于就绪状态。(也就是等待cpu的调度)
3 让处于运行状态的线程调用Thread.yield()方法 只会同优先级让步或更高优先级让步,进入就绪状态。
4 让处于运行状态的线程调用另一个线程的join()方法
当前运行的线程可以调用另一个线程的join()方法,当前运行的线程将转到阻塞状态,直至另一个线程运行结束,它才会转到就绪状态 从而有机会恢复运行。
通过一下几种途径中的一种,线程可以从被阻塞状态到可运行状态。
1 线程被置于睡眠状态,且已经经过指定的毫秒数。
2 线程正在等待I/O操作的完成,且该操作已经完成。
3 线程正在等待另一个线程所持有的锁,且另一个线程已经释放该锁的所有权;(也有可能等待超时。当超时发生时,线程解除阻塞。)
4 线程正在等待某个触发条件,且另一个线程发出了信号表明条件已经发生了变化。(如果为线程的等待设置了一个超时,那么当超时发生时该线程将解除阻塞。)
5 线程已经被挂起,且有人调用了它的resume方法。不过,由于suspend方法已经过时,resume方法也就随之被弃用了,你不应该在自己的代码里调用它。(现在应该用sleep取而代之。)
关于java线程状态转移图和线程状态流转图的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
java线程状态转移图的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于线程状态流转图、java线程状态转移图的信息别忘了在本站进行查找喔。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~