線程調度方法

本文主要介紹線程的相關調度方法

1.sleep()方法
讓當前線程暫停執⾏,從運⾏狀態進⼊阻塞狀態,將 CPU 資源讓給其他線程的調度⽅式,通過 sleep()來實現。
sleep(long millis),調⽤時需要傳⼊休眠時間,單位爲豪秒。

自定義一個線程類

public class MyThread extends Thread {

    @Override
    public void run() {
        for (int i=0;i<10;i++){
            if (i == 5){
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(i + "------MyThread1");
        }
    }
}

test類

public class MyTest {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        thread1.setName("線程1");
        thread1.start();
    }

}

控制檯上可發現運行到i = 4的時候,停了一秒鐘。


2.線程合併-join方法
合併是指將指定的某個線程加⼊到當前線程中,合併爲⼀個線程,由兩個線程交替執⾏變成⼀個線程中的兩個子線程順序執⾏。
通過調⽤ join ⽅法來實現合併,具體如何合併?
線程甲和線程⼄,線程甲執⾏到某個時間點的時候調⽤線程⼄的 join⽅法,則表示從當前時間點開始CPU 資源被線程⼄獨佔,線程甲進⼊阻塞狀態,直到線程⼄執⾏完畢,線程甲進⼊就緒狀態,等待獲取CPU 資源進⼊運⾏狀態。
join ⽅法重載,join() 表示⼄線程執⾏完畢之後才能執⾏其他線程,join(long millis) 表示⼄線程執⾏millis 毫秒之後,⽆論是否執⾏完畢,其他線程都可以和它爭奪 CPU 資源。

代碼演示:
自定義runable實現類

public class MyRunable1 implements Runnable {

    @Override
    public void run() {
        for (int i = 0;i < 200; i++){
            System.out.println("----MyRunable");
        }
    }
}

測試類

public class MyTest {
    public static void main(String[] args) {
        /*
        * sleep()
        * */
        /*MyThread thread1 = new MyThread();
        thread1.setName("線程1");
        thread1.start();*/

        /*
         * join()-線程合併
         * */
        MyRunable1 runable1 = new MyRunable1();
        Thread thread1 = new Thread(runable1);
        thread1.start();
        for (int i = 0;i < 100; i++){
            if (i == 20){
                try {
                    thread1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

            System.out.println(i + "我是主線程");
        }
    }

}

查看結果可發現,到19的時候主線程就停了,讓thread1執行完纔開始執行的。
join(1000)的效果就是,thread1執行了一秒後,主線程和thread1又開始互相搶佔資源,交替執行。


3. yield()-線程禮讓
線程禮讓是指在某個特定的時間點,讓線程暫停搶佔 CPU 資源的⾏爲,運⾏狀態/就緒狀態—》阻塞狀態,將 CPU 資源讓給其他線程來使⽤。

假如線程甲和線程⼄在交替執⾏,某個時間點線程甲做出了禮讓,所以在這個時間節點線程⼄擁有了CPU 資源,執⾏業務邏輯,但不代表線程甲⼀直暫停執⾏。

線程甲只是在特定的時間節點禮讓,過了時間節點,線程甲再次進⼊就緒狀態,和線程⼄爭奪 CPU 資源。

代碼演示:
thread1

public class MyThread1 extends Thread {
    @Override
    public void run() {
        for (int i=0;i<10;i++){
            if (i == 2){
                yield();
            }
            System.out.println(Thread.currentThread().getName()+i+"=====Thread1");
        }
    }
}

thread2

public class MyThread2 extends Thread {
    @Override
    public void run() {
        for (int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName()+i+"Thread2======");
        }

    }
}

test類

public class MyTest {
    public static void main(String[] args) {
        /*
         * sleep()
         * */
        /*MyThread thread1 = new MyThread();
        thread1.setName("線程1");
        thread1.start();*/

        /*
         * join()-線程合併
         * */
        /*MyRunable1 runable1 = new MyRunable1();
        Thread thread1 = new Thread(runable1);
        thread1.start();
        for (int i = 0;i < 100; i++){
            if (i == 20){
                try {
                    thread1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

            System.out.println(i + "我是主線程");
        }*/

        /*
         * yield()-線程合併
         * */
        MyThread1 thread1 = new MyThread1();
        thread1.setName("線程甲");
        MyThread2 thread2 = new MyThread2();
        thread2.setName("線程乙");
        thread1.start();
        thread2.start();
    }

}

效果可能有些不佳,知道意思就行。


4.線程中斷
有很多種情況會造成線程停⽌運⾏:

  • 線程執⾏完畢⾃動停⽌
  • 線程執⾏過程中遇到錯誤拋出異常並停⽌
  • 線程執⾏過程中根據需求⼿動停⽌

Java 中實現線程中斷有如下⼏個常⽤⽅法:

1.public void stop()
2.public void interrupt()
3.public boolean isInterrupted()

stop ⽅法在新版本的 JDK 已經不推薦使⽤,重點關注後兩個⽅法。

interrupt 是⼀個實例⽅法,當⼀個線程對象調⽤該⽅法時,表示中斷當前線程對象。

每個線程對象都是通過⼀個標誌位來判斷當前是否爲中斷狀態。

isInterrupted 就是⽤來獲取當前線程對象的標誌位:true 表示清除了標誌位,當前線程已經中斷;false 表示沒有清除標誌位,當前對象沒有中斷。
當⼀個線程對象處於不同的狀態時,中斷機制也是不同的。

1.創建狀態:實例化線程對象,不啓動。

public class Test {
public static void main(String[] args) {
Thread thread = new Thread();
System.out.println(thread.getState());
thread.interrupt();
System.out.println(thread.isInterrupted());
}
}

執行結果
在這裏插入圖片描述NEW 表示當前線程對象爲創建狀態,false 表示當前線程並未中斷,因爲當前線程沒有啓動,不存在中斷,不需要清除標誌位。

public class Test2 {
public static void main(String[] args) {
// MyRunnable runnable = new MyRunnable();
// Thread thread = new Thread(runnable);
// thread.start();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0; i < 10;i++) {
System.out.println(i+"---main");
}
}
});
thread.start();
System.out.println(thread.getState());
thread.interrupt();
System.out.println(thread.isInterrupted());
System.out.println(thread.getState());
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章