java多執行緒之消費生產模型-使用synchronized解決虛假喚醒
阿新 • • 發佈:2020-12-11
package com.wenshao.juc; /** * 生產者和消費者案例 * * @author Administrator * */ public class TestProductorAndConsumer { public static void main(String[] args) { Clerk clerk = new Clerk(); Productor productor = new Productor(clerk); Consumer consumer = new Consumer(clerk); new Thread(productor, "生產者 A").start(); new Thread(consumer, "消費者 B").start(); new Thread(productor, "生產者 C").start(); new Thread(consumer, "消費者 D").start(); } } class Clerk { private int product = 0; // 1. 進貨 public synchronized void get() { while(product >= 1) { // 為了避免虛假喚醒問題,wait() 應該總是使用在迴圈中 System.out.println("產品已滿"); try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + ":" + ++product); this.notifyAll(); } // 2. 賣貨 public synchronized void sale() { while (product <= 0) { System.out.println("缺貨!"); try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + ":" + --product); this.notifyAll(); } } // 生產者 class Productor implements Runnable { private Clerk clerk; public Productor(Clerk clerk) { super(); this.clerk = clerk; } @Override public void run() { for (int i = 0; i <= 20; i++) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } clerk.get(); } } } // 消費者 class Consumer implements Runnable { private Clerk clerk; public Consumer(Clerk clerk) { super(); this.clerk = clerk; } @Override public void run() { for (int i = 0; i <= 20; i++) { clerk.sale(); } } }