Java多執行緒(六)-執行緒通訊
阿新 • • 發佈:2021-10-03
七.執行緒通訊
在生產者與消費者問題中,生產者和消費者共享同一個資源,且二者之間相互依賴,互為條件。
- 對於生產者,沒有生產產品前,要通知消費者等待,生產之後要通知消費者消費。
- 對於消費者,消費之後要通知生產者生產新產品以供消費
- synochronized可阻止併發更新同一個共享資源,實現同步。但不能實現執行緒之間通訊。
解決方法:
1.管程法:生產者將生產的資料放入緩衝區,消費者從緩衝取取出資料
點選檢視程式碼
public class guancheng { public static void main(String[] args) { Container container = new Container(); new Productor(container).start(); new Consumer(container).start(); } } //產品 class Product{ int id; public Product(int id) { this.id = id; } } //消費者 class Consumer extends Thread{ Container container; public Consumer(Container container){ this.container = container; } @Override public void run() { // 消費 for (int i = 0; i < 100; i++) { Product product = container.pop(); System.out.println("消費了第"+product.id+"個產品"); } } } //生產者 class Productor extends Thread{ Container container; public Productor(Container container){ this.container = container; } @Override public void run() { // 生產 for (int i = 0; i < 100; i++) { container.push(new Product(i)); System.out.println("生產了第"+i+"個產品"); } } } //緩衝區 class Container{ Product[] products = new Product[100]; // 定義容器大小 int count = 0; public synchronized void push(Product product){ // 生產者生產產品 if (count == products.length){ // 容器滿了,通知消費者消費,停止生產 } products[count] = product; // 沒有滿,生產者生產產品 count++; } public synchronized Product pop(){ // 消費者消費產品 if (count == 0){ // 沒有產品,通知生產者生產 } count--; // 消費者消費 Product product = products[count]; return product; } }
2.訊號燈法:設定標誌位
點選檢視程式碼
public class xinhaodeng { public static void main(String[] args) { Show show = new Show(); new Player(show).start(); new Audience(show).start(); } } // 生產者 class Player extends Thread{ Show show; public Player(Show show){ this.show = show; } @Override public void run() { for (int i = 0; i < 10; i++) { if (i%2==0){ show.act("news->"+i); }else { show.act("movie->"+i); } } } } // 消費者 class Audience extends Thread{ Show show; public Audience(Show show){ this.show = show; } @Override public void run() { for (int i = 0; i < 10; i++) { show.watch(); } } } // 產品 class Show{ String show; boolean flag = true; // 表演者表演,觀眾等待true // 觀眾觀看,表演者等待false public synchronized void act(String show){ if (!flag){ // 觀眾觀看,表演者等待 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("表演者表演了"+show); this.notifyAll(); // 通知觀眾觀看 this.show = show; this.flag = !this.flag; } public synchronized void watch(){ if (flag){ // 表演者表演,觀眾等待 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("觀眾觀看了"+show); this.notifyAll(); // 通知表演者表演 this.flag = !this.flag; } }