---
# System prepended metadata

title: JAVA 多執行緒 Thread、Runnable
tags: [Java]

---

# JAVA 多執行緒 Thread、Runnable


###### tags: `Java` 

---

## 建立執行緒 Thread

### 1.直接建立 Thread 類別執行緒物件
- 宣告子類別繼承自Thread類別且子類別中還要覆寫Thread 類別的 run()方法。
- run()方法是執行緒主體，執行緒要處理事情的程式要寫在run()方法中。
- 當呼叫 Thread 類別的 start() 方法來啟動執行緒後會執行該執行緒的run()方法。
- ![](https://i.imgur.com/jPnbjmN.png)
- ![](https://i.imgur.com/j8DB7Ai.png)



### 2.宣告繼承自Thread類別的自定執行緒類別
- ![](https://i.imgur.com/aJdYfxC.png)
![](https://i.imgur.com/KF0L9QV.png)


*ps.簡言之執行緒就是可以多個程式同時或分時段執行，不再限定單一主程式執行*




---

## 實作Runnable介面來建立執行緒

前面採繼承Thread父類別方式來建立執行緒程式撰寫較簡單但彈性較小。如子類別同時又要繼承其它類別時，因 Java 每個類別只能有一個父類別(單一繼承)不允許多重繼承。為解決此問題，另提供實作 Runnable 介面。

實作 Runnable 介面時，還須要實作run()方法。使用Runnable介面所建立的新類別，只是一個準執行緒，還必須藉由準執行緒的物件來建構Thread類別的物件用以啟動執行緒，其方式如下：
![](https://i.imgur.com/F4ZNocF.png)
![](https://i.imgur.com/mfRPcsm.png)





---

## 執行緒的同步 (Synchronized)

1.避免在同時間點，有多個執行緒同時存取同個物件造成資料錯誤。
2.JVM 提供一種機制，發生多個執行緒同時存取且同時修改同個物件時，利用關鍵字synchronized 來解決物件混亂情形。
![](https://i.imgur.com/up9PuF8.png)

做法：
當執行緒進入有用 synchronized 的程式區塊時，先檢查該區塊是否已經被鎖定(lock) ？有沒有其它 Thread 物件已先進入該區塊？若沒有其它Thread物件佔住該區塊，目前Thread物件就可進入該程式區塊，同時將程式塊區鎖定以避免其它 Thread物件進入。若程式區塊已被其它 Thread 物件鎖定，Thread 物件會進入中斷態，繼續等待被鎖定程式區塊被釋放。



---

## 執行緒的等待和喚醒

1.<span class="code1">wait()</span>：讓指定執行緒進入Wait pool 成為等待狀態，每個物件都有自己專有Wait pool。

2.<span class="code1">notify()</span>：喚醒一個在Wait pool等待執行緒，哪個執行緒被喚醒由 JVM 決定。

3.<span class="code1">notifyAll()</span>：喚醒所有在 Wait pool等待執行緒，至於是哪個執行緒會先執行仍是由JVM決定。








---
<span class="code1"></span>
<style>
h2 {
    color: #2383B8;
}
h3 {
    color: #1AA340;
}
h4 {
    color: white;
    background-color: #2383B8;
    padding:8px;
}

.code1 {
    padding: 2px 4px;
    font-size: 90%;
    color: #c7254e;
    background-color: #f9f2f4;
    border-radius: 4px;
    font-family:'Fira Code';
}
.code {
    padding: 2px 4px;
    font-size: 90%;
    font-family:'Fira Code';
}
</style>