Java 多線程(三)—— 線程的生命周期及方法


 

線程的方法

1、sleep(long millis)

線程休眠:讓執行的線程暫停一段時間,進入計時等待狀態。

        static void sleep(long millis):調用此方法后,當前線程放棄 CPU 資源,在指定的時間內,sleep 所在的線程不會獲得可運行的機會,此狀態下的線程不會釋放同步鎖。

      該方法更多的是用來模擬網絡延遲,讓多線程並發訪問同一資源時的錯誤效果更加明顯。

2、wait()

線程等待:一旦一個線程執行到wait(),就釋放當前的鎖。

    注意:此方法必須在同步代碼塊或同步方法中

3、notify()/notifyAll()

喚醒:喚醒wait的一個或所有的線程

      注意:此方法需和wait()成對使用,必須在同步代碼塊或同步方法中

注意sleep()和 wait() 的區別,sleep指定時間內當前線程放棄 CPU 資源,線程不會釋放同步鎖,wait 會放棄 CPU 資源,同時也會放棄 同步鎖

4、join()

聯合線程:表示這個線程等待另一個線程完成后(死亡)才執行,join 方法被調用之后,線程對象處於阻塞狀態。寫在哪個線程中,哪個線程阻塞

    這種也稱為聯合線程,就是說把當前線程和當前線程所在的線程聯合成一個線程

5、yield()

禮讓線程:表示當前線程對象提示調度器自己願意讓出 CPU 資源。

     調用該方法后,線程對象進入就緒狀態,所以完全有可能:某個線程調用了 yield() 方法,但是線程調度器又把它調度出來重新執行。

sleep() 和 yield() 方法的區別:

  ①、都能使當前處於運行狀態的線程放棄 CPU資源,把運行的機會給其他線程

  ②、sleep 方法會給其他線程運行的機會,但是不考慮其他線程優先級的問題;yield 方法會優先給更高優先級的線程運行機會

  ③、調用 sleep 方法后,線程進入計時等待狀態,調用 yield 方法后,線程進入就緒狀態。

 

join示例:

public class TestThread1 {
    public static void main(String [] args){
        SubThread1 subThread1=new SubThread1();
        subThread1.start();
        for (int i=0;i<=100;i++){ 
           System.out.println(Thread.currentThread().getName()+":"+i);
           if(i==20){
                try {
                    subThread1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class SubThread1 extends Thread{
    @Override
    public void run(){
        for (int i=0;i<=100;i++){
            try {
                Thread.currentThread().sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

運行結果:

main:0
main:1
main:2
main:3
main:4
main:5
main:6
main:7
main:8
main:9
main:10
Thread-0:0
Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-0:9
Thread-0:10
.
.
.
Thread-0:99
Thread-0:100
main:11
main:12
main:13
main:14
main:15
.
.
main:98
main:99
main:100

運行結果分析:在main線程中調用線程A的join()方法,此時main線程停止執行,直至A線程執行完畢,main線程再接着join()之后的代碼執行

 

 線程的通信

/**
 * @author: ChenHao
 * @Description:使用兩個線程打印1-100,線程1,線程2交替打印
 * 線程通信:如下的三個關鍵字使用的話,都得在同步代碼塊或同步方法中。
 * wait():一旦一個線程執行到wait(),就釋放當前的鎖。
 * notify()/notifyAll():喚醒wait的一個或所有的線程
 * 如果不使用break,程序將不會停止
 * @Date: Created in 10:50 2018/10/29
 */
public class TestPrintNum {
    public static void main(String [] args){
        PrintNum printNum=new PrintNum();
        Thread thread1=new Thread(printNum);
        Thread thread2=new Thread(printNum);
        thread1.start();
        thread2.start();
    }
}

class PrintNum implements Runnable{
    int num=1;
    @Override
    public void run(){
        while (true){
            synchronized (this){
                notify();
                if(num<=100){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+":"+num++);
                }else {
                    break;
                }
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

運行結果:

Thread-0:1
Thread-1:2
Thread-0:3
Thread-1:4
Thread-0:5
Thread-1:6
Thread-0:7
Thread-1:8
Thread-0:9
Thread-1:10
.
.
.

運行結果分析:當第一個線程獲取鎖之后,打印后wait,釋放鎖;第二個線程獲取鎖,並喚醒第一個線程,打印后wait;交替打印

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM