很多人對于線程的狀態(tài)不是太了解,本次我想把我理解的有關(guān)線程的相關(guān)知識和大家分享一下刻两,上面的圖片是我從網(wǎng)上找到的扩灯,這張圖片對于線程的知識了解有很大的幫助。
線程的狀態(tài):
- 新建狀態(tài)(new):新創(chuàng)建了一個線程對象漏隐,該對象繼承了Therad類或?qū)崿F(xiàn)了Runnable接口,但是此時該對象沒有調(diào)用start()方法奴迅。是一個初始狀態(tài)青责。
- 就緒狀態(tài)(Runnable):線程對象創(chuàng)建后,其他線程調(diào)用了該對象的start()方法取具。該狀態(tài)的線程位于可運行的線程池中脖隶,可以運行,等待獲取CPU的時間片暇检。
- 運行狀態(tài)(Running):此時線程獲取了CPU产阱,執(zhí)行代碼。
- 阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因為某種原因放棄CPU的使用權(quán)块仆,暫時停止運行构蹬。知道線程進(jìn)入就緒狀態(tài)(Runnable)王暗,此時才有機會轉(zhuǎn)入到運行狀態(tài)。阻塞狀態(tài)分為以下幾種:
4.1. 等待阻塞(watiting):運行的線程執(zhí)行wait()方法庄敛,JVM會把該線程放入等待池中俗壹。
4.2. 超時等待阻塞(time-waiting):運行時的線程會執(zhí)行帶有超時時間的wait()方法,JVM會把該線程放入等待池中藻烤。當(dāng)超時后绷雏,線程重新轉(zhuǎn)入就緒狀態(tài)。
4.3. 同步阻塞(synchronized):運行時的線程獲取對象的同步鎖時怖亭,若該同步鎖被別的線程占用涎显,則JVM會把該線程放入鎖池中。
4.4. 其他阻塞:運行的線程執(zhí)行sleep或者join方法依许,或者執(zhí)行I/O請求時棺禾,JVM會把該線程置為阻塞狀態(tài),當(dāng)sleep狀態(tài)超時峭跳,join等待線程終止或者超時是膘婶,線程重新轉(zhuǎn)入就緒狀態(tài)。 - 死亡狀態(tài):線程執(zhí)行完畢蛀醉,該線程結(jié)束生命周期悬襟。
以下是阻塞狀態(tài)的實例,通過實例拯刁,并且配合jdk自帶的jvisualvm脊岳,我們可以看到線程的狀態(tài)。
package com.unionfin.thread;
import java.util.concurrent.TimeUnit;
public class JavaThreadState
{
public static void main(String[] args)
{
Thread waittingBlocked = new Thread(new WaitingBlocked(),
"waittingBlocked");
Thread timeWaittingBlocked = new Thread(new TimeWaitBlocked(),
"timeWaittingBlocked");
// synchronizedBlocked1,synchronizedBlocked2搶同一把鎖垛玻,只有一個可以搶到
Thread synchronizedBlocked1 = new Thread(new SynchronizedBlocked(),
"synchronizedBlocked1");
Thread synchronizedBlocked2 = new Thread(new SynchronizedBlocked(),
"synchronizedBlocked2");
// sleepBlocked線程睡了100秒割捅,在這一百秒中,其處于阻塞狀態(tài)
Thread sleepBlocked = new Thread(new sleepBlocked(), "sleepBlocked");
// 獲取主線程
Thread mainTherad = Thread.currentThread();
// 主線程調(diào)用join方法帚桩,只有joinBlocked線程死亡之后亿驾,主線程才會從阻塞中返回
Thread joinBlocked = new Thread(new JoinBlocked(mainTherad),
"joinBlocked");
waittingBlocked.start();
timeWaittingBlocked.start();
synchronizedBlocked1.start();
synchronizedBlocked2.start();
sleepBlocked.start();
joinBlocked.start();
}
}
/**
* 等待阻塞,一直處于等待狀態(tài)账嚎,知道有其他線程將其喚醒
*
* @author xiaotao
*
*/
class WaitingBlocked implements Runnable
{
public void run()
{
synchronized (WaitingBlocked.class)
{
try
{
//調(diào)用wait()方法時線程會放棄對象鎖
WaitingBlocked.class.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
/**
* 在五十秒內(nèi)處于等待狀態(tài)莫瞬,過了五十秒之后會被喚醒,進(jìn)入runnable狀態(tài)
*
* @author xiaotao
*
*/
class TimeWaitBlocked implements Runnable
{
public void run()
{
try
{
synchronized (TimeWaitBlocked.class)
{
TimeWaitBlocked.class.wait(50000);
System.out
.println("l have wait about 50 s,so i don't want to wait");
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
/**
* 該實例是一個搶鎖的阻塞實例郭蕉,兩個線程爭搶一個鎖疼邀,只有一個線程搶到鎖,另外一個線程搶不到鎖召锈,處于阻塞狀態(tài)
*
* @author xiaotao
*
*/
class SynchronizedBlocked implements Runnable
{
public void run()
{
synchronized (SynchronizedBlocked.class)
{
while (true)
{
}
}
}
}
/**
* 處于sleep阻塞狀態(tài)旁振,睡了100秒之后處于runnable狀態(tài),之后爭搶cpu。
*
* @author xiaotao
*
*/
class sleepBlocked implements Runnable
{
public void run()
{
try
{
while (true)
{
TimeUnit.SECONDS.sleep(100);
System.out.println("l have sleep 100 s");
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
class JoinBlocked implements Runnable
{
private Thread thread;
public JoinBlocked(Thread thread)
{
this.thread = thread;
}
public void run()
{
try
{
thread.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
while (true)
{
}
}
}
"joinBlocked" prio=6 tid=0x0000000006a2f000 nid=0x2604 runnable [0x00000000077ef000]
java.lang.Thread.State: RUNNABLE
at com.unionfin.thread.JoinBlocked.run(JavaThreadState.java:170)
at java.lang.Thread.run(Thread.java:662)
Locked ownable synchronizers:
- None
"sleepBlocked" prio=6 tid=0x0000000006a33000 nid=0x65c waiting on condition [0x00000000076ef000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:302)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:328)
at com.unionfin.thread.sleepBlocked.run(JavaThreadState.java:137)
at java.lang.Thread.run(Thread.java:662)
Locked ownable synchronizers:
- None
"synchronizedBlocked2" prio=6 tid=0x0000000006a35000 nid=0x2198 runnable [0x00000000075ef000]
java.lang.Thread.State: RUNNABLE
at com.unionfin.thread.SynchronizedBlocked.run(JavaThreadState.java:113)
- locked <0x000000077caf7278> (a java.lang.Class for com.unionfin.thread.SynchronizedBlocked)
at java.lang.Thread.run(Thread.java:662)
Locked ownable synchronizers:
- None
"synchronizedBlocked1" prio=6 tid=0x0000000006a24000 nid=0x251c waiting for monitor entry [0x00000000074ef000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.unionfin.thread.SynchronizedBlocked.run(JavaThreadState.java:113)
- waiting to lock <0x000000077caf7278> (a java.lang.Class for com.unionfin.thread.SynchronizedBlocked)
at java.lang.Thread.run(Thread.java:662)
Locked ownable synchronizers:
- None
"timeWaittingBlocked" prio=6 tid=0x0000000006a23000 nid=0x144c in Object.wait() [0x00000000073ef000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000077caf6af8> (a java.lang.Class for com.unionfin.thread.TimeWaitBlocked)
at com.unionfin.thread.TimeWaitBlocked.run(JavaThreadState.java:87)
- locked <0x000000077caf6af8> (a java.lang.Class for com.unionfin.thread.TimeWaitBlocked)
at java.lang.Thread.run(Thread.java:662)
Locked ownable synchronizers:
- None
"waittingBlocked" prio=6 tid=0x0000000006a21000 nid=0x1ba4 in Object.wait() [0x00000000072ef000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000077caf5960> (a java.lang.Class for com.unionfin.thread.WaitingBlocked)
at java.lang.Object.wait(Object.java:485)
at com.unionfin.thread.WaitingBlocked.run(JavaThreadState.java:61)
- locked <0x000000077caf5960> (a java.lang.Class for com.unionfin.thread.WaitingBlocked)
at java.lang.Thread.run(Thread.java:662)
Locked ownable synchronizers:
- None
以上是dump線程信息规求,我們可以看到各個線程目前所處狀態(tài)筐付。其中有一個線程比較有意思卵惦,就是joinBlocked線程阻肿,在該線程中, 我傳入一個A線程沮尿,A線程調(diào)用join()方法丛塌,此時只有joinBlocked線程死亡之后,A線程才會進(jìn)入runnable階段畜疾。
以上就是線程狀態(tài)的幾個例子赴邻,希望對大家有所幫助。