多線程 - 4.線程的休眠與活躍

isAlive() 函數

isAlive() 函數可判斷當前線程是否處於活躍狀態。

class MyThread extends Thread{
    @Override
    public void run(){
            System.out.println("運行中:" + this.isAlive());
    }
}

public class test0{
    public static void main(String[] args){
        MyThread myThread = new MyThread();
        System.out.println("開始:" + myThread.isAlive());
        myThread.start();
        System.out.println("結束:" + myThread.isAlive());
    }
}

開始:false
結束:true
運行中:true

sleep() 函數

sleep() 函數的作用是指定的毫秒內讓當前執行的線程休眠。

class MyThread extends Thread{
    @Override
    public void run(){
            System.out.println("運行中:" + this.isAlive());
    }
}

public class test1{
    public static void main(String[] args){
        MyThread myThread = new MyThread();
        System.out.println("開始:" + myThread.isAlive());
        myThread.start();
        System.out.println("結束:" + myThread.isAlive());
        try{
            myThread.sleep(1000);
        } catch(Exception exception){
            exception.printStackTrace();
        }
        System.out.println("睡眠後:" + myThread.isAlive());
    }
}

開始:false
結束:true
運行中:true
睡眠後:false

線程的生命週期

jdk1.5之後的6種狀態

  1. 新建 - New:創建後尚未啓動的線程。
  2. 運行 - Runnable:該狀態的線程可能正在執行,也可能正在等待操作系統爲它分配執行時間。
  3. 無限期等待 - Waiting:該狀態的線程不會被分配處理器執行時間,需要其他線程顯式喚醒。
  4. 限期等待 - Timed Waiting:該狀態的線程也不會被分配處理器執行時間,但是在一定時間後由系統自動喚醒。
  5. 阻塞 - Blocked:在程序等待進入同步區域後會進入該狀態,該線程需要等待一個排他鎖,當另一個線程放棄這個鎖時,該線程獲得該鎖並運行。
  6. 結束 - Terminated:已終止線程的線程狀態。
    在這裏插入圖片描述
模擬 NEW、RUNNABLE、和 TERMINATED 狀態
public class test2{
    public static void main(String[] args){
        try{
            Thread myThread = new MyThread();
            System.out.println("MyThread state 1:" + myThread.getState());
            myThread.sleep(1000);
            myThread.start();
            myThread.sleep(1000);
            System.out.println("MyThread state 2:" + myThread.getState());
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
}

class MyThread extends Thread{
    @Override
    public void run(){
        System.out.println("MyThread run()" + Thread.currentThread().getName()
         + "。該線程的狀態:" + Thread.currentThread().getState());
    }
    public MyThread(){
        System.out.println("MyThread 無參構造的線程名" + Thread.currentThread().getName()
         + "。該線程的狀態:" + Thread.currentThread().getState());
    }
}

MyThread 無參構造的線程名main。該線程的狀態:RUNNABLE
MyThread state 1:NEW
MyThread run()Thread-0。該線程的狀態:RUNNABLE
MyThread state 2:TERMINATED

模擬 TIMED_WAITING 狀態
public class test3{
    public static void main(String[] args){
        try{
            Thread myThread = new MyThread();
            myThread.start();
            myThread.sleep(1000);
            System.out.println("MyThread state 2:" + myThread.getState());
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
}

class MyThread extends Thread{
    @Override
    public void run(){
        try{
            System.out.println("sleep 開始");
            Thread.sleep(10000);
            System.out.println("sleep 結束");
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
    public MyThread(){
        System.out.println("MyThread 無參構造的線程名" + Thread.currentThread().getName()
         + "。該線程的狀態:" + Thread.currentThread().getState());
    }
}

MyThread 無參構造的線程名main。該線程的狀態:RUNNABLE
sleep 開始
MyThread state 2:TIMED_WAITING
sleep 結束

模擬 BLOCKED 狀態
public class test4 {
    public static void main(String[] args) {

        Thread threadA = new Thread(new Runnable() {
            public void run() {
               MyService.myMethod();
            }
        }, "ThradA");
        threadA.start();

        Thread threadB = new Thread(new Runnable() {
            public void run() {
                MyService.myMethod();
            }
        }, "ThradB");
        threadB.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        boolean isBlocked = threadB.getState().equals(Thread.State.BLOCKED);
        System.out.print("threadB.getState().equals(Thread.State.BLOCKED)" + isBlocked);
    }
}

class MyService{
    public static synchronized void myMethod() {
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

threadB.getState().equals(Thread.State.BLOCKED)true

  1. 這個地方的 myMethod()方法不僅加了 synchronized關鍵字,還加了 static關鍵字
  2. 如果不加 static,就達不到阻塞的效果
  3. static 表示“全局”或者“靜態”的意思,但是Java語言中沒有全局變量的概念
  4. synchronized 是實例鎖:鎖在某一個實例對象上
  5. static synchronized 是全局鎖:該鎖針對的是類,無論實例多少個對象,線程都共享該鎖
  6. 效率問題,線程B開始條件一定是線程A的結束
模擬 WAITING 狀態
public class test5 {
    public static void main(String[] args) {
        Thread myThread = new MyThread();
        myThread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("main 方法中 myThread 的狀態:" + myThread.getState());
    }
}

class myLock{
    public static final String lock = new String("0");
}

class MyThread extends Thread{
    @Override
    public void run() {
        synchronized (myLock.lock) {
            try {
                myLock.lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

main 方法中 myThread 的狀態:WAITING

  1. synchronized 的三種用法:修飾實例方法、修飾靜態方法、修飾代碼塊。
  2. 修飾代碼塊下-成員鎖:synchronized (myLock.lock) {}
  3. 修飾代碼塊下-實例對象鎖:synchronized(this) {}
  4. 修飾代碼塊下-當前類的 class 對象鎖:synchronized(AccountingSync.class) {}
  5. wait() 函數:一個對象調用了 wait 方法,必須要採用 notify() 和 notifyAll() 方法喚醒該進程
  6. wait() 函數與 sleep() 函數的區別:異常1、入參2、API3、作用範圍4、調用者的區別5、本質區別6

  1. wait() 函數不需要捕獲異常,sleep() 函數必須捕獲異常。 ↩︎

  2. wait() 函數可以傳入參數,也可以不傳入參數,sleep() 函數必須傳入參數。 ↩︎

  3. sleep() 是 Thread 類的函數,線程雖然休眠了,但依然保持着監控狀態且不會釋放鎖對象。wait() 方法是 Object 類裏的方法,當一個線程執行到 wait() 方法時,它就進入到一個和該對象相關的等待池中,同時釋放了鎖對象。 ↩︎

  4. sleep() 是靜態方法,也就是說它只對當前對象有效。wait 、 notify 和 notifyAll 方法只能在同步方法或者同步代碼塊中使用,而 sleep 方法可以在任何地方使用。 ↩︎

  5. sleep() 方法是由當前線程決定,wait() 方法是由該鎖對象決定。 ↩︎

  6. sleep() 是線程的運行狀態控制,wait() 是線程間的通信。 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章