/** * 线程通信 * 经典例题:生产者/消费者问题 * 生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处 * 取走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图 * 生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通 * 知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如 * 果店中有产品了再通知消费者来取走产品。 * 这里可能出现两个问题: * 生产者比消费者快时,消费者会漏掉一些数据没有取到。 * 消费者比生产者快时,消费者会取相同的数据。 * @Date: 2022/2/17 17:45:56 */ public class WaitTest1 { public static void main(String[] args) { Clerk clerk = new Clerk(); Thread productorThread = new Thread(new Productor(clerk)); Consumer consumer = new Consumer(clerk); Thread consumerThread = new Thread(consumer); Thread consumerThread1 = new Thread(consumer); productorThread.start(); consumerThread.start(); consumerThread1.start(); } } class Productor implements Runnable { // 生产者 Clerk clerk; public Productor(Clerk clerk) { this.clerk = clerk; } public void run() { System.out.println("生产者开始生产产品"); while (true) { try { long time = 1000 + (int)(Math.random()*9000);//1秒到10秒之间随机 Thread.sleep((int) Math.random() * 1000); } catch (InterruptedException e) { e.printStackTrace(); } clerk.addProduct(); } } } class Consumer implements Runnable { // 消费者 Clerk clerk; public Consumer(Clerk clerk) { this.clerk = clerk; } public void run() { System.out.println("消费者开始取走产品"); while (true) { try { long time = 1000 + (int)(Math.random()*9000);//1秒到10秒之间随机 Thread.sleep((int) Math.random() * 1000); } catch (InterruptedException e) { e.printStackTrace(); } clerk.getProduct(); } } } class Clerk { // 售货员 private int product = 0; public synchronized void addProduct() { if (product >= 10) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { product++; System.out.println("生产者生产了第" + product + "个产品"); notifyAll(); } } public synchronized void getProduct() { if (this.product <= 0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { System.out.println("消费者:"+Thread.currentThread().getName()+"取走了第" +product + "个产品"); product--; notifyAll(); } } }
线程安全与同步
于 2022-02-17 18:01:08 首次发布