在 Java 中,多執行緒通訊方式包含共享變數、wait/notify、信號量和管道。共享變數方便資料交換但容易出現並發問題;wait/notify 使用同步機制在執行緒之間等待和喚醒;信號量限制同時存取資源的執行緒數量;管道使用緩衝區實現執行緒間的資料傳遞。
Java 多執行緒通訊方式剖析
#多執行緒是並發程式設計中一個重要概念,它允許多個任務同時執行。為了在多執行緒環境中實現資料交換,我們需要了解各種通訊方式。本文將深入探討 Java 中常用的多執行緒通訊方式,包括共享變數、wait/notify、信號量和管道。
共享變數
共享變數是多個執行緒可以存取的全域變數。當一個執行緒修改共享變數時,其他執行緒可以看到變更。然而,共享變數容易出現並發問題,如競態條件和不可預測的行為。
實戰案例:
public class SharedVariableExample { private static int sharedCounter = 0; public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(() -> { for (int i = 0; i < 1000; i++) { sharedCounter++; } }); Thread thread2 = new Thread(() -> { for (int i = 0; i < 1000; i++) { sharedCounter--; } }); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println("最终共享计数器:" + sharedCounter); } }
wait/notify
wait/notify 是 Java 中內建的同步機制。 wait() 方法會使目前執行緒進入等待狀態,直到其他執行緒呼叫 notify() 或 notifyAll() 方法將其喚醒。
實戰案例:
public class WaitNotifyExample { private static Object lock = new Object(); private static boolean dataAvailable = false; public static void main(String[] args) throws InterruptedException { Thread producer = new Thread(() -> { synchronized (lock) { while (!dataAvailable) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("处理数据..."); } }); Thread consumer = new Thread(() -> { synchronized (lock) { dataAvailable = true; lock.notify(); } }); producer.start(); consumer.start(); producer.join(); consumer.join(); } }
信號量
信號量是一種同步機制,它允許特定數量的線程同時存取一個資源。當一個執行緒取得信號量時,信號量計數器會減少;當它釋放信號量時,計數器會增加。
實戰案例:
public class SemaphoreExample { private static Semaphore semaphore = new Semaphore(2); public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(() -> { try { semaphore.acquire(); System.out.println("线程 1 进入临界区"); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } }); Thread thread2 = new Thread(() -> { try { semaphore.acquire(); System.out.println("线程 2 进入临界区"); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } }); thread1.start(); thread2.start(); thread1.join(); thread2.join(); } }
管道
管道是一種用於執行緒之間通訊的特殊資料結構。它就像一個緩衝區,一個線程可以寫入數據,另一個線程可以讀取數據。
實戰案例:
public class PipeExample { private static PipedOutputStream pos = new PipedOutputStream(); private static PipedInputStream pis = new PipedInputStream(pos); public static void main(String[] args) throws IOException { Thread writer = new Thread(() -> { try { pos.write("你好,世界!".getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { pos.close(); } }); Thread reader = new Thread(() -> { try { byte[] data = new byte[1024]; int length = pis.read(data); System.out.println(new String(data, 0, length)); } catch (IOException e) { e.printStackTrace(); } finally { pis.close(); } }); writer.start(); reader.start(); writer.join(); reader.join(); } }
以上是Java多執行緒通訊方式剖析的詳細內容。更多資訊請關注PHP中文網其他相關文章!