1. 程式人生 > >執行緒狀態與停止、阻塞(join、yield、sleep)、基本資訊、優先順序JAVA174-177

執行緒狀態與停止、阻塞(join、yield、sleep)、基本資訊、優先順序JAVA174-177

來源:http://www.bjsxt.com/
一、S02E174_01執行緒狀態與停止執行緒
一、執行緒狀態
執行緒狀態
新生狀態:用new關鍵字和Thread類或子類建立一個執行緒物件後,該執行緒物件就處於新生狀態。處於新生狀態的執行緒有自己的記憶體空間,通過呼叫start方法進入就緒狀態(Runnable)
就緒狀態:處於就緒狀態的執行緒已經具備了執行條件,但還沒有分配到CPU,處於執行緒就緒佇列,等待系統為其分配CPU。等待狀態並不是執行狀態,當系統選定一個等待執行的Thread物件後,它就會從等待執行狀態進入執行狀態,系統挑選的動作稱之為“CPU排程”。一旦獲得CPU,執行緒就進入執行狀態並自動呼叫自己的run方法
執行狀態:

在執行狀態的執行緒執行自己的run方法中程式碼,直到呼叫其它方法而終止、或等待某資源而阻塞或完成任務而死亡。如果在給定的時間片內沒有執行結束,就會被系統給換下來回到等待執行狀態。
阻塞狀態:處於執行狀態的執行緒在某些情況下,如執行了sleep(睡眠)方法,或等待I/O裝置等資源,將讓出CPU並暫時停止自己的執行,進入阻塞狀態。在阻塞狀態的執行緒不能進入就緒狀態,只有當引起阻塞的原因消除時,如睡眠時間已到,或等待的I/O裝置空閒下來,執行緒便轉入就緒狀態,重新到就緒佇列中排隊等待,被系統選中後從原來停止的位置開始繼續執行
死亡狀態:死亡狀態是執行緒生命週期中的最後一個階段。執行緒死亡的原因有兩個。一個是正常執行的執行緒完成了它的全部工作;另一個是執行緒被強制性地終止,如通過執行stop或destroy方法來終止一個執行緒(不推薦使用這兩個方法。前者會產生異常,後者是強制終止,不會釋放鎖。)
執行緒狀態描述

二、停止執行緒
1、自然終止:執行緒體正常執行完畢
2、外部干涉:
——執行緒類中定義執行緒體使用的標識
——執行緒體使用該標識
——提供對外的方法改變該標識
——外部根據條件呼叫該方法即可

package com.test.thread.status;

public class TestStatus {
    public static void main(String[] args) {
        Study s = new Study();
        new Thread(s).start();
        //外部干涉
        for (int
i = 0; i < 100000; i++) { if(50000 == i){//外部干涉 s.stop(); System.out.println("stop...-->>" + i); } } } } class Study implements Runnable{ //執行緒類中定義執行緒體使用的標識 private boolean flag = true; @Override public void run() { //執行緒體使用該標識 while(flag){ System.out.println("study thread..."); } } //對外提供方法改變標識 public void stop(){ this.flag = false; } }

二、S02E175_01執行緒阻塞1_join_yield
三、S02E176_01執行緒阻塞2_sleep_倒計時_網路延時
1、join:合併執行緒
2、yield:暫停自己的執行緒(static方法,暫停一下,可能下一毫秒又被呼叫,這由CPU決定)
3、sleep:休眠,不釋放鎖
——1)與時間相關:倒計時
——2)模擬網路延時

package com.test.thread.status;
/**
 * join:合併執行緒
 */
public class TestJoin extends Thread {
    public static void main(String[] args) throws InterruptedException {
        TestJoin testJoin = new TestJoin();
        Thread t = new Thread(testJoin);//新生狀態
        t.start();//就緒狀態
        //CPU排程 執行

        for (int i = 0; i < 1000; i++) {
            if(50==i){
                t.join();//main阻塞,等待t執行完
            }
            System.out.println("main..."+i);
        }
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("join..."+i);
        }
    }
}
package com.test.thread.status;
/**
 * yield:暫停自己的執行緒(static方法,暫停一下,可能下一毫秒又被呼叫,這由CPU決定)
 */
public class TestYield extends Thread {
    public static void main(String[] args) {
        TestYield testYield = new TestYield();
        Thread t = new Thread(testYield);
        t.start();

        for (int i = 0; i < 1000; i++) {
            if(0==i%200){
                //暫停當前執行緒
                Thread.yield();//暫停一下,可能下一毫秒又被呼叫,這由CPU決定
            }
            System.out.println("main..."+i);
        }
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("yield..."+i);
        }
    }
}
package com.test.thread.status;

import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * 倒計時
 * 1、倒數10個數,一秒內列印一個
 * 2、倒計時
 */
public class TestSleep {
    public static void main(String[] args) throws InterruptedException {
        test1();
        test2();
    }
    /**
     * 1、倒數10個數,一秒內列印一個
     * @throws InterruptedException
     */
    public static void test1() throws InterruptedException{
        int num = 10;
        while(true){
            System.out.println(num--);
            Thread.sleep(1000);//暫停
            if(num <= 0){
                break;
            }
        }
    }
    /**
     * 2、倒計時
     * @throws InterruptedException
     */
    public static void test2() throws InterruptedException{
        Date endTime = new Date(System.currentTimeMillis() + 10*1000);
        long end = endTime.getTime();
        while(true){
            //輸出
            System.out.println(new SimpleDateFormat("mm:ss").format(endTime));
            //等待一秒
            Thread.sleep(1000);
            //構建下一秒時間
            endTime = new Date(endTime.getTime() - 1000);
            //10秒以內繼續,否則退出
            if(end-10000 > endTime.getTime()){
                break;
            }
        }
    }
}
package com.test.thread.status;
/**
 * sleep模擬網路延時
 * 引起併發問題
    ...
    路人甲搶到了44
    攻城獅搶到了44
    ...
    路人甲搶到了1
    攻城獅搶到了0
    黃牛乙搶到了-1
 */
public class TestSleep2 {
    public static void main(String[] args) {
        //真實角色
        Web12306 web = new Web12306();
        //代理
        Thread t1 = new Thread(web, "路人甲");
        Thread t2 = new Thread(web, "黃牛乙");
        Thread t3 = new Thread(web, "攻城獅");
        t1.start();
        t2.start();
        t3.start();
    }
}
class Web12306 implements Runnable {
    private int num = 50;//1到50號
    @Override
    public void run(){
        while(true) {
            if(num <= 0){
                break;//跳出迴圈
            }
            try {
                Thread.sleep(500);//t1、t2、t3可能都在等待,num可能相同或為-1
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "搶到了" + num--);
        }
    }
}

四、S02E177_01執行緒基本資訊_優先順序
執行緒基本資訊

package com.test.thread.info;

public class MyThread implements Runnable {
    private boolean flag = true;
    private int num = 0;

    @Override
    public void run() {
        while(flag){
            System.out.println(Thread.currentThread().getName()+ "-->>" + num++);
        }
    }
    public void stop(){
        flag = !flag;
    }
}
package com.test.thread.info;
/**
 * Thread.currentThread
 * setName()
 * getName()
 * isAlive
 */
public class InfoDemo {
    public static void main(String[] args) throws InterruptedException {
        MyThread it = new MyThread();
        Thread proxy = new Thread(it,"挨踢");
        proxy.setName("test");
        System.out.println(proxy.getName());
        System.out.println(Thread.currentThread().getName());//main

        proxy.start();      
        System.out.println("啟動後的狀態:" + proxy.isAlive());
        Thread.sleep(50);
        it.stop();
        Thread.sleep(100);//stop後,CPU不一定立即停止,休眠一下看一下效果
        System.out.println("停止後的狀態:" + proxy.isAlive());
    }
}
package com.test.thread.info;
/**
 * 優先順序:概率,不是絕對的先後順序
 * MAX_PRIORITY 10
 * NORM_PRIORITY    5(預設)
 * MIN_PRIORITY 0
 * 
 * setPriority()
 * getPriority()
 */
public class InfoPriority {
    public static void main(String[] args) throws InterruptedException {
        MyThread it1 = new MyThread();
        Thread p1 = new Thread(it1,"挨踢1");
        MyThread it2 = new MyThread();
        Thread p2 = new Thread(it2,"挨踢2");

        p1.setPriority(Thread.MIN_PRIORITY);
        p2.setPriority(Thread.MAX_PRIORITY);
        p1.start();
        p2.start();

        Thread.sleep(100);
        it1.stop();
        it2.stop();
    }
}