Java的知识点28——线程的生命周期
線程的生命周期
一個線程對象在它的生命周期內,需要經歷5個狀態。
1.? 新生狀態(New):?用new關鍵字建立一個線程對象后,該線程對象就處于新生狀態。處于新生狀態的線程有自己的內存空間,通過調用start方法進入就緒狀態。
2. 就緒狀態(Runnable):?處于就緒狀態的線程已經具備了運行條件,但是還沒有被分配到CPU,處于“線程就緒隊列”,等待系統為其分配CPU。就緒狀態并不是執行狀態,當系統選定一個等待執行的Thread對象后,它就會進入執行狀態。一旦獲得CPU,線程就進入運行狀態并自動調用自己的run方法。有4中原因會導致線程進入就緒狀態:
? ? ??1. 新建線程:調用start()方法,進入就緒狀態;
? ? ??2. 阻塞線程:阻塞解除,進入就緒狀態;
? ? ??3. 運行線程:調用yield()方法,直接進入就緒狀態;
? ? ??4. 運行線程:JVM將CPU資源從本線程切換到其他線程。
3. 運行狀態(Running):在運行狀態的線程執行自己run方法中的代碼,直到調用其他方法而終止或等待某資源而阻塞或完成任務而死亡。如果在給定的時間片內沒有執行結束,就會被系統給換下來回到就緒狀態。也可能由于某些“導致阻塞的事件”而進入阻塞狀態。
4. 阻塞狀態(Blocked):阻塞指的是暫停一個線程的執行以等待某個條件發生(如某資源就緒)。有4種原因會導致阻塞:
? ? ??1. 執行sleep(int millsecond)方法,使當前線程休眠,進入阻塞狀態。當指定的時間到了后,線程進入就緒狀態。
? ? ??2. 執行wait()方法,使當前線程進入阻塞狀態。當使用nofity()方法喚醒這個線程后,它進入就緒狀態。
? ? ??3. 線程運行時,某個操作進入阻塞狀態,比如執行IO流操作(read()/write()方法本身就是阻塞的方法。只有當引起該操作阻塞的原因消失后,線程進入就緒狀態。
? ? ??4. join()線程聯合: 當某個線程等待另一個線程執行結束后,才能繼續執行時,使用join()方法。
5. 死亡狀態(Terminated):?死亡狀態是線程生命周期中的最后一個階段。線程死亡的原因有兩個。一個是正常運行的線程完成了它run()方法內的全部工作; 另一個是線程被強制終止,如通過執行stop()或destroy()方法來終止一個線程(注:stop()/destroy()方法已經被JDK廢棄,不推薦使用)。當一個線程進入死亡狀態以后,就不能再回到其它狀態了。
終止線程
?* 1. 線程正常執行完畢--》次數
?* 2. 外部干涉--》加入標識
?* 不要使用stop destroy
/*** 終止線程* 1. 線程正常執行完畢--》次數* 2. 外部干涉--》加入標識* 不要使用stop destroy* @author Administrator**/
public class TerminateThread implements Runnable{//1. 加入標識 標記線程體是否可以運行private boolean flag=true;private String name;public TerminateThread(String name) {this.name = name;}@Overridepublic void run() {int i=0;//2.關聯標識, true-->運行 false-->停止while(flag) {System.out.println(name+"---->"+i++); }}//3.對外提供方法改變標識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模擬網絡延時、倒計時
sleep模擬網絡延時,放大了發生問題的可能性
/*** sleep模擬網絡延時,放大了發生問題的可能性* @author Administrator**/ public class BlockedSleep01 implements Runnable{//票數private int ticketNums=99;@Overridepublic void run() {while(true) {if(ticketNums<0) {break;}//模擬延時try {Thread.sleep(200); //相當于網絡延時問題。會造成數據的不準確性} 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());//多個代理new Thread(web,"馬畜").start();new Thread(web,"碼農").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);//比賽是否結束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 模擬倒計時
/*** sleep 模擬倒計時* @author Administrator**/ public class BlockedSleep03 {/*** @param args* @throws InterruptedException*/public static void main(String[] args) throws InterruptedException {// 倒數10個數,一秒一個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 模擬倒計時* @author Administrator**/ public class BlockedSleep03 {public static void main(String[] args) throws InterruptedException {//倒計時Date endTime=new Date(System.currentTimeMillis()+1000*10); //倒計時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 {// 倒數10個數,一秒一個int num=10;while(true) {Thread.sleep(1000);System.out.println(num--);if(num<0) {break;}}} }yield 禮讓線程,暫停線程 ?直接進入就緒狀態 而不是進入阻塞狀態
/*** yield 禮讓線程,暫停線程 直接進入就緒狀態 而不是進入阻塞狀態* @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(); //禮讓 從運行態到就緒態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:合并線程 插隊線程
/*** join:合并線程 插隊線程* @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(); //插隊 main主線程被阻塞了}System.out.println("main....."+i);}} }總結
以上是生活随笔為你收集整理的Java的知识点28——线程的生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java的知识点27——lambda推导
- 下一篇: java的知识点29——join:合并线