Java并發(fā)編程基礎(chǔ)(一)線程簡介

一、什么是線程


現(xiàn)代操作系統(tǒng)調(diào)度的最小單元是線程,在一個進(jìn)程里可以創(chuàng)建多個線程,這些線程都擁有各自的計(jì)數(shù)器、堆棧和局部變量等屬性,并且能夠訪問共享的內(nèi)存變量。處理器在這些線程上高速切換,讓使用者感覺到這些線程在同時執(zhí)行。

二、為什么要使用多線程


  • 更多的處理器核心

一個單線程程序在運(yùn)行時只能使用一個處理器核心,那么再多的處理器核心加入也無法顯著提升該程序的執(zhí)行效率。相反,如果該程序使用多線程技術(shù),將計(jì)算邏輯分配到多個處理器核心上,就會顯著減少程序的處理時間,并且隨著更多處理器核心的加入而變得更有效率。

  • 更快的響應(yīng)時間

有時我們會編寫業(yè)務(wù)較為復(fù)雜的代碼。例如,一筆訂單的創(chuàng)建,它包括插入訂單數(shù)據(jù)、生成訂單快照、發(fā)送郵件通知賣家和記錄貨品銷售數(shù)量??梢允褂枚嗑€程技術(shù),將數(shù)據(jù)一致性不強(qiáng)的操作派發(fā)給其他線程處理(也可以使用消息隊(duì)列),如生成訂單快照、發(fā)送郵件等。好處是響應(yīng)用戶請求的線程能夠盡可能快地處理完成,縮短了響應(yīng)時間,提升用戶體驗(yàn)。

三、線程優(yōu)先級


現(xiàn)代操作系統(tǒng)基本采用分時的形式調(diào)度運(yùn)行線程,操作系統(tǒng)會分出一個個時間片,線程會分配到若干時間片,當(dāng)線程的時間片用完了就會發(fā)生線程調(diào)度,等待下次分配。線程優(yōu)先級就是決定線程需要多或者少分配一些處理器資源的線程屬性。

通過一個整型成員變量priority來控制優(yōu)先級,優(yōu)先級范圍從1~10,在線程構(gòu)建時可以通過setPriority(int)方法來修改線程優(yōu)先級,默認(rèn)優(yōu)先級是5。線程優(yōu)先級不能作為程序正確性的依賴,許多操作系統(tǒng)都是完全不理會Java線程對于優(yōu)先級的設(shè)定的。

四、線程的狀態(tài)


狀態(tài)名稱 說明
NEW 初始狀態(tài),線程被構(gòu)建,但是還沒有調(diào)用start()方法
RUNNABLE 運(yùn)行狀態(tài),就緒和 運(yùn)行中兩種狀態(tài)都稱作運(yùn)行中
BLOCKED 阻塞狀態(tài),標(biāo)識線程阻塞于鎖
WAITING 等待狀態(tài),表示線程進(jìn)入等待狀態(tài),進(jìn)入該狀態(tài)表示當(dāng)前線程需要等待其他線程做出一些特定動作(通知或中斷)
TIME_WAITING 超時等待狀態(tài),不同于WAITING,它可以在指定時間自行返回
TERMINATED 終止?fàn)顟B(tài),表示當(dāng)前線程已經(jīng)執(zhí)行完畢
// ThreadState.java
public class ThreadState {
    
    public static void main(String[] args) {
        new Thread(new TimeWaiting(), "TimeWaitingThread").start();
        new Thread(new Waiting(), "WaitingThread").start();
        // 使用兩個Blocked線程, 一個獲取鎖成功, 另一個被阻塞
        new Thread(new Blocked(), "BlockedThread-1").start();
        new Thread(new Blocked(), "BlockedThread-2").start();
    }
    
    // 該線程不斷的進(jìn)行睡眠
    static class TimeWaiting implements Runnable {
        @Override
        public void run() {
            while (true) {
                SleepUtils.second(100);
            }
        }
    }
    
    // 該線程在Waiting.class實(shí)例上等待
    static class Waiting implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (Waiting.class) {
                    try {
                        Waiting.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    // 該線程在Blocked.class 實(shí)例上加鎖后,不會釋放該鎖
    static class Blocked implements Runnable {
        public void run() {
            synchronized (Blocked.class) {
                while (true) {
                    SleepUtils.second(100);
                }
            }
        }
    }
    

}
// SleepUtils.java
public class SleepUtils {
    
    public static final void second(long seconds) {
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException e) {
            
        }
    }

}

命令行輸入“jps”,得到ThreadState的進(jìn)程id(如929)后,輸入“jstack 929”,嘗試查看示例進(jìn)程運(yùn)行時的線程信息:

// BlockedThread-2 線程阻塞在獲取Blocked.class示例的鎖上
"BlockedThread-2" prio=5 tid=0x00007feacb05d000 nid=0x5d03 waiting for monitor entry 
[0x000000010fd58000]
        java.lang.Thread.State: BLOCKED (on object monitor)

// BlockedThread-1 線程獲取到了Blocked.class的鎖
"BlockedThread-1" prio=5 tid=0x00007feacb05a000 nid=0x5b03 waiting on condition
[0x000000010fc55000]
        java.lang.Thread.State: TIME_WAITING (sleeping)

// WaitingThread線程在Waiting實(shí)例上等待
"WaitingThread" prio=5 tid=0x00007feacb059800 nid=0x5903 in Object.wait()
[0x000000010fb52000]
        java.lang.Thread.State: WAITING (on object monitor)

// TimeWaitingThread 線程處于超時等待
"TimeWaitingThread" prio=5 tid=0x00007feacb058800 nid=0x5703 waiting on condition
[0x000000010fa4f000]
        java.lang.Thread.State: TIMED_WAITING (sleeping)
java線程狀態(tài)變遷

五、守護(hù)線程


Daemon線程是一種支持型線程,因?yàn)樗饕挥米鞒绦蛑泻笈_調(diào)度以及支持性工作。這意味著,當(dāng)一個Java虛擬機(jī)中不存在非Daemon線程的時候,Java虛擬機(jī)將會退出。因此,不能依靠Daemon線程的finally塊中的內(nèi)容來確保執(zhí)行關(guān)閉或清理資源的邏輯。
可以通過Thread.setDaemon(true)將線程設(shè)置為Daemon線程。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容