生产者消费者问题_Java高并发编程-生产者消费者问题

生产者消费者模型

f1383b74efd34b76325dc28aace7a996.png

思路一

通过实际问题构造一个生产者和消费者问题,用馒头类,放馒头的框,生产馒头的厨师类,和吃馒头的消费者类,其中后两者实现Runnable接口,然后通过创建多个线程来生产馒头和消费馒头;

代码实现一

public class Main { public static void main(String[] args) { Bucket b = new Bucket(6); Producer p = new Producer(b); Consumer c = new Consumer(b); new Thread(p).start(); new Thread(c).start(); }}class Mantou { @Override public String toString() { return "Mantou:" + id; } int id; Mantou(int id) { this.id = id; }}class Bucket { int max, index; Mantou[] m; Bucket(int max) { this.max = max; index = -1; m = new Mantou[max]; } synchronized void push(Mantou m1) { while (index == max-1) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); m[++ index] = m1; } synchronized Mantou pop() { while (index == -1) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); return m[index --]; }}class Producer implements Runnable { Bucket b = null; Producer(Bucket b) { this.b = b; } @Override public void run() { for (int i=0; i<20; i++) { Mantou m = new Mantou(i); System.out.println("生产了:" + m); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } b.push(m); } }}class Consumer implements Runnable { Bucket b = null; Consumer(Bucket b) { this.b = b; } @Override public void run() { for (int i=0; i<20; i++) { Mantou m = b.pop(); System.out.println("消费了:" + m); } }}

思路二

通过创建同步容器来模拟生产者和消费者的问题;

代码实现二

package useful;import java.util.ArrayList;import java.util.List;public class MyContainer { private final int max = 10; private final List list = new ArrayList<>();// private int count = 0; synchronized void put(T t) { while (list.size() == max) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); list.add(t);// count ++; } synchronized T get() { while (list.size() == 0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll();// count --; return list.remove(list.size()-1); } public static void main(String[] args) { MyContainer m = new MyContainer<>(); for (int i=0; i<10; i++) { new Thread(() -> { for (int j=0; j<5; j++) System.out.println(Thread.currentThread().getName() + " consumed " + m.get()); }, "c" + i).start();; } for (int i=0; i<10; i++) { new Thread(() -> { for (int j=0; j<5; j++) { m.put(Thread.currentThread().getName() + ":" + j); } }, "p" + i).start();; } }}

思路三

利用Lock和Condition实现并发访问;可以精确控制到让哪一个或者哪一种线程唤醒;

代码如下

package useful;import java.util.ArrayList;import java.util.List;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class MyContainer { private final int max = 10; private final List list = new ArrayList<>(); Lock lock = new ReentrantLock(); private Condition producer = lock.newCondition(); private Condition consumer = lock.newCondition(); void put(T t) { try { lock.lock(); while (list.size() == max) { producer.await(); } list.add(t); consumer.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } synchronized T get() { T t = null; try { lock.lock(); while (list.size() == 0) { consumer.await(); } t = list.get(list.size()-1); producer.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } return t; } public static void main(String[] args) { MyContainer m = new MyContainer<>(); for (int i=0; i<10; i++) { new Thread(() -> { for (int j=0; j<5; j++) System.out.println(Thread.currentThread().getName() + " consumed " + m.get()); }, "c" + i).start();; } for (int i=0; i<10; i++) { new Thread(() -> { for (int j=0; j<5; j++) { m.put(Thread.currentThread().getName() + ":" + j); } }, "p" + i).start();; } }}

本文链接:https://blog.csdn.net/rebornyp/article/details/79277859

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值