Thread之一:线程生命周期及六种状态

更新时间:2023-06-30 10:14:06 阅读: 评论:0

Thread之⼀:线程⽣命周期及六种状态
《》
《》
《》
⼀、线程的⽣命周期及五种基本状态
fuckaway关于Java中线程的⽣命周期,⾸先看⼀下下⾯这张较为经典的图:
上图中基本上囊括了Java中多线程各重要知识点。掌握了上图中的各知识点,Java中的多线程也就基本上掌握了。主要包括:
Java线程具有七种基本状态
新建状态(New):⾄今尚未启动的线程的状态。线程刚被创建,但尚未启动。如:Thread t = new MyThread();
就绪状态(Runnable):当调⽤线程对象的start()⽅法(t.start();),线程即进⼊就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执⾏,并不是说执⾏了t.start()此线程⽴即就会执⾏;
运⾏状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执⾏,即进⼊到运⾏状态。注:就绪状态是进⼊到运⾏状态的唯⼀⼊⼝,也就是说,线程要想进⼊运⾏状态执⾏,⾸先必须处于就绪状态中;
⽆限期等待(Waiting):位于对象等待池中的阻塞状态(Blocked in object’s wait pool):当线程处于运⾏状态时,如果执⾏了某个对象的wait()⽅法,Java虚拟机就会把线程放到这个对象的等待池中,这涉及到“线程通信”的内容。处于这种状态的线程不会被分配处理器执⾏时间,它们要等待被其他线程显⽰唤醒。以下⽅法会让线程陷⼊⽆限期的等待状态:
没有设置timeout参数的Object::wait()⽅法
没有设置timeout参数的Thread::join()⽅法
LockSupport::park()⽅法
asonal限期等待(Timed Waiting):处于这种状态的线程也不会被分配处理器执⾏时间,不过⽆须等待其他线程显⽰唤醒,在⼀定时间后它们由系统⾃动唤醒。以下⽅法会让线程进⼊期限等待状态:
Thread::sleep()⽅法
设置了timeout参数的Object::wait()⽅法
设置了timeout参数的Thread::join()⽅法
LockSupport::parkNanos()⽅法
LockSupport::parkUntil()⽅法
阻塞状态(Blocked):处于运⾏状态中的线程由于某种(当线程处于运⾏状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他线程占⽤,Java虚拟机就会把这个线程放到这个对象的锁池中,这涉及到“线程同步”的内容。【线程在获取synchronized同步锁失败(因为锁被其它线程所占⽤)】)原因,暂时放弃对CPU的使⽤权,停⽌执⾏,此时进⼊阻塞状态,直到其进⼊到就绪状态,才有机会再次被CPU调⽤以进⼊到运⾏状态。
“阻塞状态”与“等待状态”的区别:“阻塞状态”在等待着获取⼀个排它锁,这个事件将在另⼀个线程放弃这个锁的时候发⽣;⽽“等待状态”则是在等待⼀段时间,或者唤醒动作发⽣。在程序进⼊同步区域的时候,线程就会进⼊阻塞状态。
死亡状态(Dead):线程执⾏完了或者因异常退出了run()⽅法,该线程结束⽣命周期。
JVM线程运⾏状态 (JVM Thread Status)
爱词霸在线翻译在中定义了线程的状态:
⾄今尚未启动的线程的状态。线程刚被创建,但尚未启动。
可运⾏线程的线程状态。线程正在JVM中执⾏,有可能在等待操作系统中的其他资源,⽐如处理器。
受阻塞并且正在等待监视器的某⼀线程的线程状态。处于受阻塞状态的某⼀线程正在等待监视器锁,以便进⼊⼀个同步的块/⽅法,或者在调⽤ Object.wait 之后再次进⼊同步的块/⽅法。
在Thread Dump⽇志中通常显⽰为java.lang.Thread.State: BLOCKED (on object monitor)。
某⼀等待线程的线程状态。线程正在⽆期限地等待另⼀个线程来执⾏某⼀个特定的操作,线程因为调⽤下⾯的⽅法之⼀⽽处于等待状态:
不带超时的 Object.wait ⽅法,⽇志中显⽰为java.lang.Thread.State: WAITING (on object monitor)
不带超时的 Thread.join ⽅法
LockSupport.park ⽅法,⽇志中显⽰为java.lang.Thread.State: WAITING (parking)
指定了等待时间的某⼀等待线程的线程状态。线程正在等待另⼀个线程来执⾏某⼀个特定的操作,并设定了指定等待的时间,线程因为调⽤下⾯的⽅法之⼀⽽处于定时等待状态:
Thread.sleep ⽅法
指定超时值的 Object.wait ⽅法
指定超时值的 Thread.join ⽅法
LockSupport.parkNanos
LockSupport.parkUntil
线程处于终⽌状态。
根据Java Doc中的说明,在给定的时间上,⼀个只能处于上述的⼀种状态之中,并且这些状态都是JVM的状态,跟操作系统中的线程状态⽆关。cay
JAVA虚拟机启动程序步骤:
(1) Main是启动时候的主线程,即程序⼊⼝
(2)在main函数结束后,虚拟机会⾃动启动⼀个DestroyJavaVM线程,该线程会等待所有ur thread 线程结束后退出(即,只剩下daemon 线程和DestroyJavaVM线程⾃⼰,整个虚拟机就退出,此时daemon线程被终⽌),因此,如果不希望程序退出,只要创建⼀个⾮daemon的⼦线程,让线程不停的sleep即可。
线程的创建
Thread类,有⼀个start⽅法,即启动该线程。启动的线程会执⾏该类的run⽅法。注意:因为启动线程时要执⾏某个过程,因此,通常是需要重新实现run⽅法的
线程的结束
run模块执⾏完成主动退出,或者被其他线程强⾏终⽌。
通过jstack pid &
线程状态样例
等待状态样例
"IoWaitThread" prio=6 tid=0x0000000007334800 nid=0x2b3c waiting on condition [0x000000000893f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
-
parking to wait for  <0x00000007d5c45850> (a urrent.locks.AbstractQueuedSynchronizer$ConditionObject)
国庆黑板报内容at urrent.locks.LockSupport.park(LockSupport.java:156)
at urrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987)
at urrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:440)
at urrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:629)
at com.nbp.theplatform.threaddump.ThreadIoWaitState$IoWaitHandler2.run(ThreadIoWaitState.java:89)
at java.lang.Thread.run(Thread.java:662)
上⾯例⼦中,IoWaitThread 线程保持等待状态并从 LinkedBlockingQueue 接收消息,如果 LinkedBlockingQueue ⼀直没有消息,该线程的状态将不会改变。
阻塞状态样例
"BLOCKED_TEST pool-1-thread-1" prio=6 tid=0x0000000006904800 nid=0x28f4 runnable [0x000000000785f000]
java.lang.Thread.State: RUNNABLE
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:282)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
- locked <0x0000000780a31778> (a java.io.BufferedOutputStream)
at java.io.PrintStream.write(PrintStream.java:432)
- locked <0x0000000780a04118> (a java.io.PrintStream)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:85)
- locked <0x0000000780a040c0> (a java.io.OutputStreamWriter)
absolutelyat java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:168)
at java.wLine(PrintStream.java:496)
- locked <0x0000000780a04118> (a java.io.PrintStream)
at java.io.PrintStream.println(PrintStream.java:687)
- locked <0x0000000780a04118> (a java.io.PrintStream)
at com.nbp.theplatform.itorLock(ThreadBlockedState.java:44)
- locked <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)
at com.nbp.theplatform.threaddump.ThreadBlockedState$1.run(ThreadBlockedState.java:7)
at urrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at urrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Locked ownable synchronizers:
- <0x0000000780a31758> (a urrent.locks.ReentrantLock$NonfairSync)
"BLOCKED_TEST pool-1-thread-2" prio=6 tid=0x0000000007673800 nid=0x260c waiting for monitor entry [0x0000000008abf000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.nbp.theplatform.itorLock(ThreadBlockedState.java:43)
- waiting to lock <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)
at com.nbp.theplatform.threaddump.ThreadBlockedState$2.run(ThreadBlockedState.java:26)
at urrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at urrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Locked ownable synchronizers:
- <0x0000000780b0c6a0> (a urrent.locks.ReentrantLock$NonfairSync)
"BLOCKED_TEST pool-1-thread-3" prio=6 tid=0x00000000074f5800 nid=0x1994 waiting for monitor entry [0x0000000008bbf000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.nbp.theplatform.itorLock(ThreadBlockedState.java:42)
- waiting to lock <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)
at com.nbp.theplatform.threaddump.ThreadBlockedState$3.run(ThreadBlockedState.java:34)
at urrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886
at urrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Locked ownable synchronizers:
- <0x0000000780b0e1b8> (a urrent.locks.ReentrantLock$NonfairSync)
在上⾯的例⼦中,BLOCKED_TEST pool-1-thread-1 线程占⽤了 <0x0000000780a000b0> 锁,然⽽ BLOCKED_TEST pool-1-thread-2 和BLOCKED_TEST pool-1-thread-3 threads 正在等待获取锁。
死锁状态样例
maybe"DEADLOCK_TEST-1" daemon prio=6 tid=0x000000000690f800 nid=0x1820 waiting for monitor entry [0x000000000805f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.nbp.theplatform.threaddump.MonitorDeadlock(ThreadDeadLockState.java:197)
- waiting to lock <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
at com.nbp.theplatform.threaddump.itorOurLock(ThreadDeadLockState.java:182)
- locked <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
Locked ownable synchronizers:
- None
"DEADLOCK_TEST-2" daemon prio=6 tid=0x0000000006858800 nid=0x17b8 waiting for monitor entry [0x000000000815f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.nbp.theplatform.threaddump.MonitorDeadlock(ThreadDeadLockState.java:197)
- waiting to lock <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
at com.nbp.theplatform.threaddump.itorOurLock(ThreadDeadLockState.java:182)
- locked <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
祝你好运Locked ownable synchronizers:
现在进行时的句子怪物史莱克2插曲- None
"DEADLOCK_TEST-3" daemon prio=6 tid=0x0000000006859000 nid=0x25dc waiting for monitor entry [0x000000000825f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.nbp.theplatform.threaddump.MonitorDeadlock(ThreadDeadLockState.java:197)
- waiting to lock <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
at com.nbp.theplatform.threaddump.itorOurLock(ThreadDeadLockState.java:182)
- locked <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
Locked ownable synchronizers:
- None
上⾯的例⼦中,当线程 A 需要获取线程 B 的锁来继续它的任务,然⽽线程 B 也需要获取线程 A 的锁来继续它的任务的时候发⽣的。在thread dump 中,你能看到 DEADLOCK_TEST-1 线程持有 0x00000007d58f5e48 锁,并且尝试获取 0x00000007d58f5e60 锁。你也能看到 DEADLOCK_TEST-2 线程持有 0x00000007d58f5e60,并且尝试获取 0x00000007d58f5e78,同时 DEADLOCK_TEST-3 线程持有
0x00000007d58f5e78,并且在尝试获取 0x00000007d58f5e48 锁,如你所见,每个线程都在等待获取另外⼀个线程的锁,这状态将不会被改变直到⼀个线程丢弃了它的锁。
⽆限等待的Runnable状态样例
"socketReadThread" prio=6 tid=0x0000000006a0d800 nid=0x1b40 runnable [0x00000000089ef000]
java.lang.Thread.State: RUNNABLE
at java.SocketInputStream.socketRead0(Native Method)
at ad(SocketInputStream.java:129)
at sun.nio.adBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.ad(StreamDecoder.java:158)
- locked <0x00000007d78a2230> (a java.io.InputStreamReader)
at sun.nio.ad0(StreamDecoder.java:107)
- locked <0x00000007d78a2230> (a java.io.InputStreamReader)
at sun.nio.ad(StreamDecoder.java:93)
at java.ad(InputStreamReader.java:151)
at com.nbp.theplatform.threaddump.ThreadSocketReadState$1.run(ThreadSocketReadState.java:27)
at java.lang.Thread.run(Thread.java:662)
上例中线程的状态是RUNNABLE,但在下⾯的堆栈⽇志中发现socketReadThread 线程正在⽆限等待读取 socket,因此不能单纯通过线程的状态来确定线程是否处于阻塞状态,应该根据详细的堆栈信息进⾏分析。

本文发布于:2023-06-30 10:14:06,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/1070015.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:线程   状态   等待   处于   启动   就绪   获取   上图
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图