跳到主要內容

Concurrency - 多執行緒

  


頻道需要你的支持,謝謝你成為我們的會員(加入會員)

影片1 多執緒程式的基本觀念與建立 Thread 類別



影片2 Thread, Runnable 的使用與 ExecutorService 的基本觀念與建置



影片3 ExecutorService, Runnable, Callable, Future 的使用 未發布

影片4 多執行緒程式的同步, 非同步的基本觀念與建置 未發布

影片5 多執行緒程式的同步化方式與 Atomic package 類別的使用 未發布

影片6 CyclicBarrier 與 Thread-Safe Collections 未發布

範例


一、多執行緒程式

多執行緒程式將程式分成多個獨立的執行單元,稱為「執行緒」。每一個執行緒都可以獨立執行,並與其他執行緒同時運行。作業系統會在這些執行緒之間快速切換,讓它們看起來像是同時執行。

多執行緒程式的好處:

l   提升效能: 特別是在多CPU處理器上,多執行緒可以充分利用每個CPU,加快程式執行速度。

l   增強回應性: 即使程式的一部分被阻塞(例如等待網路回應),其他部分仍然可以繼續執行,保持程式的回應性。

l   提高資源利用率: 多執行緒可以更有效地利用系統資源,例如 CPU 和記憶體。

l   簡化程式設計: 對於某些類型的應用程式,例如圖形用戶界面和網路伺服器,多執行緒可以簡化程式設計。

 

二、Thread / Runnable

Java 中,Thread 類別和 Runnable 介面都是用來建立和管理執行緒的工具,但它們有一些關鍵的差異:

1.      定義方式

A.         Thread:是一個類別,你可以透過繼承 Thread 類別來建立執行緒類別。

B.         Runnable:是一個介面,你可以透過實作 Runnable 介面來建立執行緒類別。

2.      繼承限制

A.         Thread:由於 Java 不支援多重繼承,如果你已經繼承了其他類別,就無法再繼承 Thread

B.         Runnable:可以透過實作 Runnable 介面來建立執行緒,同時還可以繼承其他類別,保有程式設計的彈性。

3.      建立執行緒

A.         Thread

                            i.                建立一個繼承 Thread 的類別。

                          ii.                覆寫 run() 方法,在其中定義執行緒要執行的程式碼。

                        iii.                建立 Thread 類別的實例。

                        iv.                呼叫 start() 方法啟動執行緒。

B.         Runnable

                            i.                建立一個實作 Runnable 介面的類別。

                          ii.                實作 run() 方法,在其中定義執行緒要執行的程式碼。

                        iii.                建立 Runnable 類別的實例。

                        iv.                建立 Thread 類別的實例,並將 Runnable 實例作為參數傳遞給 Thread 的建構函式。

                          v.                呼叫 start() 方法啟動執行緒。

 

三、ExecutorService

Java 中,ExecutorService 是一個介面,它提供了一種更有效率且更易於管理的方式來處理多執行緒。它可以讓你提交任務並讓執行緒池中的執行緒來執行這些任務,而不用手動建立和管理個別的執行緒。

1.      基本觀念

ExecutorService 的核心概念是執行緒池。執行緒池會預先建立一定數量的執行緒,並將提交的任務分配給這些執行緒執行。這樣可以避免頻繁地建立和銷毀執行緒,提高效率並降低資源消耗。

2.      建立 ExecutorService

Java 中,您可以透過 Executors 類別提供的工廠方法來取得 ExecutorService 的實例。這些工廠方法提供不同的執行緒池配置,以滿足不同的需求。以下說明兩種常見的 ExecutorService 取得方式及其差異:

l   Executors.newFixedThreadPool(int count)

l   Executors.newCachedThreadPool()

3.      提交任務

l   使用 execute() 方法將任務提交給 ExecutorService

l   使用 submit() 方法將任務提交給 ExecutorService

4.      關閉 ExecutorService

當你不再需要 ExecutorService 時,應該呼叫 shutdown() 方法來關閉它。shutdown() 方法會停止接受新的任務,並等待所有已提交的任務完成後再關閉執行緒池。

 

四、Callable / Future

1.      Callable<T>

l   Callable<T> 是一個介面,它定義了一個 T call() 方法。

l   T call() 方法封裝了您想要非同步執行的任務邏輯,並且它可以返回一個結果。

2.      Future<T>

l   Future<T> 是一個介面,它表示一個計算的結果。

l   它提供了一些方法來檢查計算是否完成、等待計算完成、以及獲取計算的結果。

l   Future<T> 的泛型類型指定了計算返回的結果類型。

 

五、Synchronized / Asynchronized

在程式設計中,Synchronized(同步)和 Asynchronized(非同步)代表了兩種截然不同的執行模型,它們對程式流程、資源管理和用戶體驗都有深遠的影響。

1.      多執行緒程式預設為 Asynchronized

2.      設定 Synchronized

l   方法宣告

l   區塊宣告

3.      Static synchronization

l   方法宣告

l   區塊宣告

 

六、atomic package

java.util.concurrent.atomic package提供了強大的工具,用於在 Java 中實現高效率、執行緒安全的程式碼。透過使用 atomic類別,您可以避免傳統鎖定機制帶來的成本,同時確保多執行緒環境下的資料一致性。

 

七、CyclicBarrier

CyclicBarrier Java 中一種強大的同步工具,它能夠有效地協調多個執行緒的執行,確保它們在關鍵時刻同步。透過合理地使用 CyclicBarrier,您可以更好地管理多執行緒程式,提高程式的並行性和效率。

 

八、Thread-Safe Collections

Java 提供了多種執行緒安全的集合,讓您能夠在多執行緒環境中安全地操作集合資料。選擇合適的集合,並遵循正確的使用方式,可以幫助您構建高效能、可靠的多執行緒應用程式。

1.      ConcurrentHashMap

HashMap 的執行緒安全版本。

2.      CopyOnWriteArrayList

ArrayList 的執行緒安全版本。

3.      ConcurrentSkipListMap

TreeMap的執行緒安全版本。

4.      ConcurrentSkipListSet

TreeSet 的執行緒安全版本。

5.      BlockingQueue

常見的實作類別包括ArrayBlockingQueueLinkedBlockingQueue PriorityBlockingQueue

n   一種特殊的 Queue,支援阻塞操作。

n   當佇列為空時,從佇列中獲取元素的執行緒將被阻塞,直到有元素可用。

n   當佇列已滿時,向佇列中添加元素的執行緒將被阻塞,直到有空間可用。