天天看點

好程式員:大資料之線程進階部分

好程式員:大資料之線程進階部分,首先講一下線程的生命周期

對于一個線程, 在被建立後, 不是立即就進入到了運作狀态, 也不是一直處于運作狀态, 線上程的聲明周期中, 一個線程會在多種狀态之間進行切換

new : 新生狀态, 線程被執行個體化, 但是還沒有開始執行(start)

runnable: 就緒狀态, 已經執行過start, 線程已經啟動了, 隻是沒有搶到CPU時間片

running: 運作狀态, 搶到了CPU時間片

blocked: 阻塞狀态, 線程執行的過程中, 遇到一些特殊情況, 會進入阻塞狀态. 阻塞中的線程, 是不能參數時間片的搶奪的 (不能被線程排程器排程)

dead: 死亡狀态, 線程終止

​ 正常死亡 : run方法中的代碼執行結束

​ 非正常死亡 : 強制使用stop方法停止這個線程

臨界資源問題

由于線程之間是資源共享的。如果有多個線程,同時對一個資料進行操作,此時這個資料會出現問題。

如果有一個線程在通路一個臨界資源,在通路之前,先對這個資源“上鎖”,此時如果有其他的線程也需要通路這個臨界資源,需要先查這個資源有沒有被上鎖,如果沒有被上鎖,此時這個線程可以通路這個資源;如果上鎖了,則此時這個線程進入阻塞狀态,等待解鎖。

####同步代碼段

// 同步代碼段
// 小括号:就是鎖
// 大括号:同步代碼段,一般情況下,寫需要對臨界資源進行的操作
synchronized () {

}
// 關于同步鎖:可以分成兩種:對象鎖、類鎖
//           
####同步方法
// 使用synchronized關鍵字修飾的方法就是同步方法
// 将一個方法中所有的代碼進行一個同步
// 相當于将一個方法中所有的代碼都放到一個synchronized代碼段中
// 同步方法的鎖:
// 1. 如果這個方法是一個非靜态方法:鎖是this
// 2. 如果這個方法是一個靜态方法:鎖是類鎖(目前類.class)
private synchronized void sellTicket() {
}           

lock與unlock

就是一個類RenntrantLock

線程死鎖(了解)

在解決臨界資源問題的時候,我們引入了一個"鎖"的概念。我們可以用鎖對一個資源進行保護。實際,在多線程的環境下,有可能會出現一種情況:

假設有A和B兩個線程,其中線程A持有鎖标記a,線程B持有鎖标記b,而此時,線程A等待鎖标記b的釋放,線程B等待鎖标記a的釋放。這種情況,叫做 死鎖

生産者消費者設計模式

wait() 、notify() 、notifyAll()

wait(): 等待。使得目前的線程釋放鎖标記,進入等待隊列。可以使目前的線程進入阻塞狀态。

notify(): 喚醒,喚醒等待隊列中的一個線程。

notifyAll(): 喚醒,喚醒等待隊列中所有的線程。

wait和sleep的差別:

  1. 兩個方法都可以使一個線程進入阻塞。
  2. 差別:wait方法會釋放鎖标記,sleep則不會釋放鎖标記。

    ####懶漢式單例設計模式中的線程安全問題

    線程池

    ThreadPoolExecutor類是線程池最核心的類。這個類的構造方法中的幾個參數:

int corePoolSize: 核心線程數量。核心池大小。

int maxmiunPoolSize: 線程池中最多的線程數量。

long keepAliveTime: 核心線程之外的臨時線程,能存活的時間。(從這個線程空閑的時候開始算)

TimeUnit unit: 上面的時間機關

​ NANOSECONDS: 納秒

​ MICROSECONDS: 微秒

​ MILLISEONDS: 毫秒

​ SECONDS: 秒

​ MINUTES: 分

​ HOURS: 時

​ DAYS: 天

BlockingQueue<Runnable> workQueue: 等待隊列

​ ArrayBlockingQueue

  1. 網絡程式設計
  2. TCP
  3. UDP

繼續閱讀