700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > java的知识点34——线程通信 || 生产者与消费者问题

java的知识点34——线程通信 || 生产者与消费者问题

时间:2023-12-25 03:59:52

相关推荐

java的知识点34——线程通信 || 生产者与消费者问题

线程通信

应用场景:生产者和消费者问题

• 假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取走消费

• 如果仓库中没有产品,则生产者将产品放入仓库,否则停止生产并等待,直到仓库中的产品被消费者取走为止

• 如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,直到仓库中再次放入产品为止

分析

• 这是一个线程同步问题,生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,互为条件

• 对于生产者,没有生产产品之前,要通知消费者等待。而生产了产品之后,又需要马上通知消费者消费

• 对于消费者,在消费之后,要通知生产者已经消费结束,需要继续生产新产品以供消费

• 在生产者消费者问题中,仅有synchronized是不够的

• synchronized可阻止并发更新同一个共享资源,实现了同步

• synchronized不能用来实现不同线程之间的消息传递(通信)

Java提供了3个方法解决线程之间的通信问题

线程通信解决方式一:

并发协作模型“生产者/消费者模式” ——》管程法

生产者:生产者指的是负责生产数据的模块(这里模块可能是:方法、对象、线程、进程)

消费者:消费者指的是负责处理数据的模块(这里模块可能是:方法、对象、线程、进程)

缓冲区:消费者不能直接使用生产者的数据,它们之间有个“缓冲区”。生产者将生产好的数据放入“缓冲区”,消费者从“缓冲区”拿要处理的数据

缓冲区是实现并发的核心,缓冲区的设置有3个好处:

实现线程的并发协作

有了缓冲区以后,生产者线程只需要往缓冲区里面放置数据,而不需要管消费者消费的情况;同样,消费者只需要从缓冲区拿数据处理即可,也不需要管生产者生产的情况。 这样,就从逻辑上实现了“生产者线程”和“消费者线程”的分离。

解耦了生产者和消费者

生产者不需要和消费者直接打交道。

解决忙闲不均,提高效率

生产者生产数据慢时,缓冲区仍有数据,不影响消费者消费;消费者处理数据慢时,生产者仍然可以继续往缓冲区里面放置数据

协作模型:生产者消费者实现方式一:管程法 借助缓冲区

/*** 协作模型:生产者消费者实现方式一:管程法* 借助缓冲区* @author Administrator**/public class CoTest01 {public static void main(String[] args) {SynContainer container=new SynContainer();new Productor(container).start();new Consumer(container).start();}}//生产者class Productor extends Thread{SynContainer container;public Productor(SynContainer container) {this.container = container;}@Overridepublic void run() {//生产for(int i=1;i<=20;i++) {System.out.println("生产第--》"+i+"个馒头");container.push(new Steamedbun(i));}}}//消费者class Consumer extends Thread{SynContainer container;public Consumer(SynContainer container) {this.container = container;}public void run() {//消费for(int i=1;i<=20;i++) {System.out.println("消费第-->"+container.pop().id+"个馒头");}}}//缓冲区class SynContainer{Steamedbun[] buns=new Steamedbun[10]; //存储容器int count=0; //计数器 // 存储 生产public synchronized void push(Steamedbun bun) {//何时能生产 容器存在空间//不能生产 只能等待if(count == buns.length) {System.out.println("------"+buns.length+"-----------");try {this.wait(); //线程阻塞 消费者通知生产解除} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} }//存在空间 可以生产////先指向空的,再放东西进去。 放一个东西,计数加1 这样做是错误的,因为导致count计数不一致//count++;//buns[count]=bun;buns[count]=bun;count++;//存在数据了,可以通知消费啦this.notifyAll();}//获取 消费public synchronized Steamedbun pop() {//何时消费 容器中是否存在数据//没有数据 只有等待if(count==0) {try {this.wait(); //线程阻塞 生产者通知消费解除} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} }//存在数据可以消费count--;Steamedbun bun=buns[count];this.notifyAll(); //存在空间了,可以唤醒对方生产了return bun;}}//馒头class Steamedbun{int id;public Steamedbun(int id) {this.id=id;}}

为什么有这种情况????

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。