Java的知识点28——线程的生命周期
線程的生命周期
一個(gè)線程對象在它的生命周期內(nèi),需要經(jīng)歷5個(gè)狀態(tài)。
1.? 新生狀態(tài)(New):?用new關(guān)鍵字建立一個(gè)線程對象后,該線程對象就處于新生狀態(tài)。處于新生狀態(tài)的線程有自己的內(nèi)存空間,通過調(diào)用start方法進(jìn)入就緒狀態(tài)。
2. 就緒狀態(tài)(Runnable):?處于就緒狀態(tài)的線程已經(jīng)具備了運(yùn)行條件,但是還沒有被分配到CPU,處于“線程就緒隊(duì)列”,等待系統(tǒng)為其分配CPU。就緒狀態(tài)并不是執(zhí)行狀態(tài),當(dāng)系統(tǒng)選定一個(gè)等待執(zhí)行的Thread對象后,它就會進(jìn)入執(zhí)行狀態(tài)。一旦獲得CPU,線程就進(jìn)入運(yùn)行狀態(tài)并自動(dòng)調(diào)用自己的run方法。有4中原因會導(dǎo)致線程進(jìn)入就緒狀態(tài):
? ? ??1. 新建線程:調(diào)用start()方法,進(jìn)入就緒狀態(tài);
? ? ??2. 阻塞線程:阻塞解除,進(jìn)入就緒狀態(tài);
? ? ??3. 運(yùn)行線程:調(diào)用yield()方法,直接進(jìn)入就緒狀態(tài);
? ? ??4. 運(yùn)行線程:JVM將CPU資源從本線程切換到其他線程。
3. 運(yùn)行狀態(tài)(Running):在運(yùn)行狀態(tài)的線程執(zhí)行自己run方法中的代碼,直到調(diào)用其他方法而終止或等待某資源而阻塞或完成任務(wù)而死亡。如果在給定的時(shí)間片內(nèi)沒有執(zhí)行結(jié)束,就會被系統(tǒng)給換下來回到就緒狀態(tài)。也可能由于某些“導(dǎo)致阻塞的事件”而進(jìn)入阻塞狀態(tài)。
4. 阻塞狀態(tài)(Blocked):阻塞指的是暫停一個(gè)線程的執(zhí)行以等待某個(gè)條件發(fā)生(如某資源就緒)。有4種原因會導(dǎo)致阻塞:
? ? ??1. 執(zhí)行sleep(int millsecond)方法,使當(dāng)前線程休眠,進(jìn)入阻塞狀態(tài)。當(dāng)指定的時(shí)間到了后,線程進(jìn)入就緒狀態(tài)。
? ? ??2. 執(zhí)行wait()方法,使當(dāng)前線程進(jìn)入阻塞狀態(tài)。當(dāng)使用nofity()方法喚醒這個(gè)線程后,它進(jìn)入就緒狀態(tài)。
? ? ??3. 線程運(yùn)行時(shí),某個(gè)操作進(jìn)入阻塞狀態(tài),比如執(zhí)行IO流操作(read()/write()方法本身就是阻塞的方法。只有當(dāng)引起該操作阻塞的原因消失后,線程進(jìn)入就緒狀態(tài)。
? ? ??4. join()線程聯(lián)合: 當(dāng)某個(gè)線程等待另一個(gè)線程執(zhí)行結(jié)束后,才能繼續(xù)執(zhí)行時(shí),使用join()方法。
5. 死亡狀態(tài)(Terminated):?死亡狀態(tài)是線程生命周期中的最后一個(gè)階段。線程死亡的原因有兩個(gè)。一個(gè)是正常運(yùn)行的線程完成了它run()方法內(nèi)的全部工作; 另一個(gè)是線程被強(qiáng)制終止,如通過執(zhí)行stop()或destroy()方法來終止一個(gè)線程(注:stop()/destroy()方法已經(jīng)被JDK廢棄,不推薦使用)。當(dāng)一個(gè)線程進(jìn)入死亡狀態(tài)以后,就不能再回到其它狀態(tài)了。
終止線程
?* 1. 線程正常執(zhí)行完畢--》次數(shù)
?* 2. 外部干涉--》加入標(biāo)識
?* 不要使用stop destroy
/*** 終止線程* 1. 線程正常執(zhí)行完畢--》次數(shù)* 2. 外部干涉--》加入標(biāo)識* 不要使用stop destroy* @author Administrator**/
public class TerminateThread implements Runnable{//1. 加入標(biāo)識 標(biāo)記線程體是否可以運(yùn)行private boolean flag=true;private String name;public TerminateThread(String name) {this.name = name;}@Overridepublic void run() {int i=0;//2.關(guān)聯(lián)標(biāo)識, true-->運(yùn)行 false-->停止while(flag) {System.out.println(name+"---->"+i++); }}//3.對外提供方法改變標(biāo)識public void terminate() {this.flag=false;}public static void main(String[] args) {TerminateThread tt=new TerminateThread("止兮");new Thread(tt).start();for(int i=0;i<=99;i++) {if(i==88) {tt.terminate();//線程的終止System.out.println("tt game over");}System.out.println("main-->"+i);}}}
sleep模擬網(wǎng)絡(luò)延時(shí)、倒計(jì)時(shí)
sleep模擬網(wǎng)絡(luò)延時(shí),放大了發(fā)生問題的可能性
/*** sleep模擬網(wǎng)絡(luò)延時(shí),放大了發(fā)生問題的可能性* @author Administrator**/ public class BlockedSleep01 implements Runnable{//票數(shù)private int ticketNums=99;@Overridepublic void run() {while(true) {if(ticketNums<0) {break;}//模擬延時(shí)try {Thread.sleep(200); //相當(dāng)于網(wǎng)絡(luò)延時(shí)問題。會造成數(shù)據(jù)的不準(zhǔn)確性} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName()+"--->"+ticketNums--);}// TODO Auto-generated method stub}public static void main(String[] args) {//一份資源BlockedSleep01 web=new BlockedSleep01();System.out.println(Thread.currentThread().getName());//多個(gè)代理new Thread(web,"馬畜").start();new Thread(web,"碼農(nóng)").start();new Thread(web,"碼蝗").start();} }sleep 模擬休息
//sleep 模擬休息 public class BlockedSleep02 implements Runnable{private String winner; //勝利者@Overridepublic void run() {for(int steps=1;steps<=100;steps++) {//模擬兔子休息if(Thread.currentThread().getName().equals("rabbit")&&steps%10==0) {try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}System.out.println(Thread.currentThread().getName()+"--->"+steps);//比賽是否結(jié)束boolean flag=gameOver(steps);if(flag) {break;}}}private boolean gameOver(int steps) {if(winner!=null) {//存在勝利者return true;}else {if(steps==100) {winner=Thread.currentThread().getName();System.out.println("winner==>"+winner);return true;}}return false;}public static void main(String[] args) {BlockedSleep02 BlockedSleep02=new BlockedSleep02();new Thread(BlockedSleep02,"tortoise").start();new Thread(BlockedSleep02,"rabbit").start();} }sleep 模擬倒計(jì)時(shí)
/*** sleep 模擬倒計(jì)時(shí)* @author Administrator**/ public class BlockedSleep03 {/*** @param args* @throws InterruptedException*/public static void main(String[] args) throws InterruptedException {// 倒數(shù)10個(gè)數(shù),一秒一個(gè)int num=10;while(true) {Thread.sleep(1000);System.out.println(num--);if(num<0) {break;}}} } import java.text.SimpleDateFormat; import java.util.Date;/*** sleep 模擬倒計(jì)時(shí)* @author Administrator**/ public class BlockedSleep03 {public static void main(String[] args) throws InterruptedException {//倒計(jì)時(shí)Date endTime=new Date(System.currentTimeMillis()+1000*10); //倒計(jì)時(shí)10秒long end=endTime.getTime();while(true) {System.out.println(new SimpleDateFormat("mm:ss").format(endTime));Thread.sleep(1000);endTime=new Date(endTime.getTime()-1000);if(end-10000>endTime.getTime()) {break;}}}public static void test() throws InterruptedException {// 倒數(shù)10個(gè)數(shù),一秒一個(gè)int num=10;while(true) {Thread.sleep(1000);System.out.println(num--);if(num<0) {break;}}} }yield 禮讓線程,暫停線程 ?直接進(jìn)入就緒狀態(tài) 而不是進(jìn)入阻塞狀態(tài)
/*** yield 禮讓線程,暫停線程 直接進(jìn)入就緒狀態(tài) 而不是進(jìn)入阻塞狀態(tài)* @author Administrator**/ public class YieldDemo01 {public static void main(String[] args) {MyYield my=new MyYield();new Thread(my,"a").start();new Thread(my,"b").start();} }class MyYield implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"-->start");Thread.yield(); //禮讓 從運(yùn)行態(tài)到就緒態(tài)System.out.println(Thread.currentThread().getName()+"-->end");}} public class YieldDemo02 {public static void main(String[] args) {new Thread(()->{for(int i=0;i<100;i++) {System.out.println("lambda……"+i);}}) .start();for(int i=0;i<100;i++) {if(i%20==0) {Thread.yield(); //main線程禮讓}System.out.println("main....."+i);}} }join:合并線程 插隊(duì)線程
/*** join:合并線程 插隊(duì)線程* @author Administrator**/ public class BlockedJoin01 {public static void main(String[] args) throws InterruptedException {Thread t= new Thread(()->{for(int i=0;i<100;i++) {System.out.println("lambda……"+i);}});t.start();for(int i=0;i<100;i++) {if(i==20) {t.join(); //插隊(duì) main主線程被阻塞了}System.out.println("main....."+i);}} }總結(jié)
以上是生活随笔為你收集整理的Java的知识点28——线程的生命周期的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java的知识点27——lambda推导
- 下一篇: java的知识点29——join:合并线