溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java線程中常用的操作有哪些

發(fā)布時間:2022-05-18 11:14:05 來源:億速云 閱讀:147 作者:iii 欄目:開發(fā)技術

本篇內容介紹了“Java線程中常用的操作有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

線程的常用操作

設置線程名字:setName()

獲取線程名稱:getName()

線程唯一Id:getId()

// 自定義線程名稱
String threadName = "threadName";
// 構造方法方式
Thread thread = new Thread(() -> {
    System.out.println("線程名=" + Thread.currentThread().getName());
},threadName);
// set方法方式
// thread.setName(threadName);
System.out.println("線程唯一Id=" + thread.getId());

線程啟動:start()

判斷線程是否存活:isAlive()

// 線程啟動
thread.start();
System.out.println("是否為存活線程=" + thread.isAlive());

線程方法:run() /call()

線程啟動后會去調用的方法。線程要做什么就在run/call方法寫,不需要直接調用,線程啟動后自己會去調用run() /call()。如果程序沒有啟動線程直接調用run/call,那么就不屬于多線程編程,是屬于當前線程直接調用普通方法一樣。

獲取當前線程對象:currentThread()

操作當前線程的非static方法,得先拿到線程對象才可以

// 獲取當前線程對象
Thread currentThread = Thread.currentThread();
// 對當前線程做一些操作
System.out.println(currentThread.getName());
try {
    // sleep 靜態(tài)方法則不需要
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}

關于線程的狀態(tài)控制(生命周期)的操作可以參考上一篇文章。

守護線程(后臺線程)

普通線程(用戶線程)的守護者,守護線程的任務是為其他的線程提供服務。如果進程中沒有了用戶線程,那么守護線程也就沒有存在的意義,JVM也隨之結束。典型的守護線程有JVM的垃圾回收線程,操作系統(tǒng)的啟動也會啟動各種模塊的守護線程。

設置線程為守護線程:setDaeman()

注意:該方法必須在start() 方法之前調用

public static void main(String[] args) {
    Thread thread = new Thread(() -> {
        System.out.println("線程名="+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 這一句不會打印出來,因為main線程(目前唯一的普通線程)等待1秒后已經結束了
        System.out.println("守護線程的狀態(tài)=" + Thread.currentThread().getState());
    });
    // 守護線程
    thread.setDaemon(true);
    // 線程啟動
    thread.start();
    System.out.println("是否為守護線程=" + thread.isDaemon());
}

線程串行化

執(zhí)行join() 方法的線程進入等待喚醒狀態(tài)(WAITING),直到調用該方法的線程結束后再由等待喚醒狀態(tài)轉為可運行狀態(tài)(RUNNABLE)。join() 方法是Thread類中的方法,其底層是使用wait() 方法來實現線程等待,待線程isAlive()為false 時才

實現線程的串行化:一個線程調用另一個線程對象的join() 來實現線程串行化執(zhí)行。

舉個例子:一道好菜

public class DemoCooking {
    
    public static void main(String[] args) {
        Thread mainThread = Thread.currentThread();
        // 1.買菜
        Thread buyThread = new Thread(new CookingThread(mainThread,"買菜"),"buyThread");
        // 2.洗菜
        Thread washThread = new Thread(new CookingThread(buyThread,"洗菜"),"washThread");
        // 3.切菜
        Thread cutThread = new Thread(new CookingThread(washThread,"切菜"),"cutThread");
        // 4.炒菜
        Thread scrambleThread = new Thread(new CookingThread(cutThread,"炒菜"),"scrambleThread");

        // 不受線程啟動順序的影響
        scrambleThread.start();
        washThread.start();
        cutThread.start();
        buyThread.start();
        
        // main線程先執(zhí)行完才可以開始:買菜
        System.out.println("開始準備……");
    }

    public static class CookingThread implements Runnable{
        private final Thread thread;
        private final String job;

        public CookingThread(Thread thread, String job){
            this.thread = thread;
            this.job = job;
        }
        @Override
        public void run() {
            String name = Thread.currentThread().getName()+":";
            try {
                thread.join();

                System.out.println(name + job + "開始");
                Thread.sleep(1000);
                System.out.println(name + job + "結束");
                Thread.sleep(1000); // 偷懶下
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

執(zhí)行結果:main > buyThread > washThread > cutThread > scrambleThread > 結束

開始準備……
buyThread:買菜開始
buyThread:買菜結束
washThread:洗菜開始
washThread:洗菜結束
cutThread:切菜開始
cutThread:切菜結束
scrambleThread:炒菜開始
scrambleThread:炒菜結束

線程優(yōu)先級

設置當前線程的優(yōu)先級,線程優(yōu)先級越高,線程可能獲得執(zhí)行的次數越多,Java線程的優(yōu)先級用整數表示,優(yōu)先級的范圍為1-10,默認為5。

setPriority(int)方法:設置線程的優(yōu)先級。

getPriority方法:獲取線程的優(yōu)先級。

public static void main(String[] args) {

    Thread thread = new Thread(() -> {
        System.out.println("線程1");
    });
    thread.setPriority(10);
    Thread thread1 = new Thread(() -> {
        System.out.println("線程2");
    });
    thread1.setPriority(1);
    thread.start();
    thread1.start();

    System.out.println("線程默認的優(yōu)先級為=" + Thread.currentThread().getPriority());

}

線程中斷

使用interrupt() 方法設置線程中斷標志=true,讓線程受到“阻塞”時拋出一個中斷信號。如果線程處于阻塞、等待喚醒或超時等待狀態(tài)(Object.wait, Thread.join和Thread.sleep)時,那么它將接收到一個中斷異常(InterruptedException),從而提前被結束該狀態(tài)。反之,如果線程是處于“可運行”(RUNNABLE)狀態(tài),那么中斷標志將沒有作用。

案例一:線程中斷有效

public static void main(String[] args) {
    Thread thread = new Thread(() -> {
        System.out.println("線程1");
        try {
            // 鬧鐘1分鐘后響
            Thread.sleep(60000);
            System.out.println("鬧鐘響了");
        } catch (InterruptedException e) {
            // 提前退出超時等待狀態(tài)
            System.out.println("發(fā)生異常,提前醒了,鬧鐘沒響手動關了");
        }

        System.out.println("繼續(xù)執(zhí)行該線程的后續(xù)程序……");

    });
    thread.setPriority(1);
    thread.start();
    thread.interrupt();
    System.out.println("main線程將thread 終端狀態(tài)設置為 "+thread.isInterrupted());
}

執(zhí)行結果:

main線程將thread 終端狀態(tài)設置為 true
線程1
發(fā)生異常,提前醒了,鬧鐘沒響手動關了
繼續(xù)執(zhí)行該線程的后續(xù)程序……

案例二:線程中斷無效

public static void main(String[] args) {
    Thread thread1 = new Thread(() -> {
        System.out.println("線程" + Thread.currentThread().getName());
        while (true) {
            System.out.print(Thread.currentThread().getState() + "\t");
        }
    });
    thread1.start();
    thread1.interrupt();
}

執(zhí)行結果:線程一直打印自己的狀態(tài)為RUNNABLE。

“Java線程中常用的操作有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI