线程协作——生产者消费者问题

2024-04-28 09:58

本文主要是介绍线程协作——生产者消费者问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 生产者消费者问题

    1. 如果仓库中只能存放一件商品,生产者将生产出来的商品放进仓库,消费者将仓库中的商品取走
    2. 如果仓库中没有商品,则生产者将商品放入仓库,否则停止生产并等待,知道仓库中的商品被消费者取走
    3. 如果仓库中有商品,则消费者直接取走商品,否则停止消费并等待,直到仓库中再次放入商品
    方法名作用
    wait()表示线程一直等待,直到其它线程通知,与sleep不同,会释放锁
    wait(long timeout)指定等待的毫秒数
    notify()唤醒一个处于等待状态的线程
    notifyAll()唤醒同一个对象上所有调用wait()方法的线程,优先级别高的线程优先调度

    注意:均是Object类的方法,都只能在同步方法或者同步代码块中使用,否则会抛出异常

  • 管程法

    • 生产者:负责生产数据的模块(可能是方法,对象,线程,进程)
    • 消费者:负责处理数据的模块(可能是方法,对象,线程,进程)
    • 缓冲区:消费者不能直接使用生产者的数据,他们之间有个缓冲区;生产者将生产好的数据放进缓冲区,消费者从缓冲区拿出数据

    方法一:管程法

    //管程法
    public class TestPC{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 = 0; i < 100; i++){container.push(new Product(i));System.out.println("生产了" + i + "只鸡");}}
    }//消费者
    class Consumer extends Thread{SynContainer container;public Consumer(SynContainer container){this.container = container;}//消费@Overridepublic void run(){for(int i = 0; i < 100; i++){System.out.println("消费了第" + container.pop().id + "只鸡");}}
    }//产品
    class Product{int id; //产品编号public Product(int id){this.id = id;}
    }//缓冲区
    class SynContainer{//需要一个容器大小Product[] products = new Product[10];//容器计数器int count = 0;//生产者放入产品public synchronized void push(Product product){//如果容器满了,就需要等待消费者消费if(count == products.length){//通知消费者消费,生产者等待try{this.wait();}catch(InterruptedException e){e.printStackTrace();}}//如果没有满,放入商品products[count] = product;count++;//通知消费者消费this.notifyAll(); }//消费者消费产品public synchronized Product pop(){//判断能否消费if(count == 0){//通知生产者生产,消费者等待try{this.wait();}catch(InterruptedException e){e.printStackTrace();}}//如果可以消费count--;Product product = products[count];//通知生产者生产this.notifyAll();return product;}
    }
    

    方法二:信号灯法

    //信号灯法:标志位解决
    public class TestPC{public static void main(String[] args){TV tv = new TV();new Player(tv).start();new Watcher(tv).start();}
    }//生产者--->演员
    class Player extends Thread{TV tv;public Player(TV tv){this.tv = tv;}@Overridepublic void run(){for(int i = 0; i < 20; i++){if(i%2 == 0){this.tv.play("快乐大本营");}else{this.tv.play("抖音");}}}
    }//消费者--->观众
    class Watcher extends Thread{TV tv;public Watcher(TV tv){this.tv = tv;}@Overridepublic void run(){for(int i = 0; i < 20; i++){tv.watch();}}
    }//产品--->节目
    class TV{//演员表演,观众等待 T//观众观看,演员等待 FString voice; //表演的节目boolean flag = true;//表演public synchronized void play(String voice){if(!flag){try{this.wait();}catch(InterruptedException e){e.printStackTrace();}}System.out.println("演员表演了:" + voice);//通知观众观看this.notifyAll();this.voice = voice;this.flag = !this.flag;}//观看public synchronized void watch(){if(flag){try{this.wait();}catch(InterruptedException e){e.printStackTrace();}}System.out.println("观众观看了:" + voice);//通知演员表演this.notifyAll();this.flag = !this.flag;}
    }
    
  • 线程池

    • 提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建销毁、实现重复利用

    • 好处:

      • 提高响应速度(减少了创建新线程的时间)
      • 降低资源消耗(重复利用线程池中线程,不需要每次都创建)
      • 便于线程管理
        • corePoolSize:核心池的大小
        • maximumPoolSize:最大线程数
        • keepAliveTime:线程没有任务时最多保持多长时间后会终止
    • JDK5.0起提供了线程池相关API:ExecutorService和Executors

    • ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor

      • void execute(Runnable command):执行任务/命令,没有返回值,一般用来执行Runnable
      • < T > Future< T > submit(Callable< T > task):执行任务,有返回值,一般用来执行Callable
      • void shutdown():关闭连接池
    • Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池

    //测试线程池
    public class TestPool{public static void main(String[] args){//创建服务,创建线程池//newFixedThreadPool 参数为:线程池的大小ExecutorService service = Executors.newFixedThreadPool(10);service.execute(new MyThread());service.execute(new MyThread());service.execute(new MyThread());service.execute(new MyThread());//关闭连接service.shutdown();}
    }class MyThread implements Runnable{@Overridepublic void run(){System.out.println(Thread.currentThread().getName());}
    }
    

这篇关于线程协作——生产者消费者问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/942947

相关文章

线程纵横:C++并发编程的深度解析与实践

hello !大家好呀! 欢迎大家来到我的Linux高性能服务器编程系列之《线程纵横:C++并发编程的深度解析与实践》,在这篇文章中,你将会学习到C++新特性,并发编程,以及其如何带来的高性能的魅力,以及手绘UML图来帮助大家来理解,希望能让大家更能了解网络编程技术!!! 希望这篇文章能对你有所帮助,大家要是觉得我写的不错的话,那就点点免费的小爱心吧!(注:这章对于高性能服务器的架构非常重要哟!

常见磁盘分区问题

给磁盘分区有几个主要的原因: 组织和管理数据:分区可以帮助用户更好地组织和管理数据。例如,你可以在一个分区上安装操作系统,而在另一个分区上存储个人文件。这样,即使操作系统崩溃或需要重新安装,你的个人文件也不会受到影响。 提高性能:在物理硬盘上,数据读写速度在磁盘的不同部分可能会有所不同。通过合理的分区,可以将常用的数据放在性能较好的区域,从而提高系统的整体性能。 多操作系统:如果你想在同一台

java中含中文字符串的编码和解码问题。

1、在Java开发中经常被文字乱码的问题困扰。下面全面解释下字符串的编码和解码。 如 String str = "中国" 编码:byte[] bts = str.getBytes("编码方式");//常用编码方式 gbk、utf-8、gb2312、iso-8859-1等等。 解码:String b = new String(bts,"解码方式");//解码方式对应常用编码方式。 2、

关于Java中的内存泄漏问题及注意事项

所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中。java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉。由于Java 使用有向图的方式进行垃圾回收管理,可以消除引用循环的问题,例如有两个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的,例如下面的代码可以看到这种情况的内存回收

(done) NLP+HMM 协作,还有维特比算法

参考视频:https://www.bilibili.com/video/BV1aP4y147gA/?p=2&spm_id_from=pageDriver&vd_source=7a1a0bc74158c6993c7355c5490fc600 (这实际上是 “序列标注任务”) HMM 的训练和预测如下图 训练过程:我们首先先给出一个语料文本,这个语料文本每个词组都分配了一个“词性”。在训练过程中

关于.9图片Eclipse上移植到AndroidStudio上的问题解决方案

在eclipse上.9图能够正常使用,但是到了Androidstudio上就报错无法引用,提示关于.9图的问题。 可以看出Androidstudio对.9图进行了更严格的定义 以下给出了两个解决方案供大家参考。  解决方案: 1. 如果一张图片不是.9图的话,图片的后缀名千万不要带有XXXX.9.png,这样在androidstudio上是非法,会报错。 2.

Java多线程(一)线程状态及线程创建方式

Java多线程编程作为每一个Android Coder都必须掌握的技术,今天我们就来聊一聊关于Java多线程的点点滴滴。Android沿用了Java的线程模型,一个Android应用创建时会开启一个线程,这个线程就是我们熟知的主线程,也叫UI线程。如果我们在主线程直接进行网络请求,系统会直接报错,提示不能在主线程请求网络,至于问什么,是因为网络访问是一个耗时的操作,如果网络访问很慢,就会导致ANR

解决ubuntu 暂时不能解析域名“cn.archive.ubuntu.com”问题

问题描述 E: 无法下载 http://security.ubuntu.com/ubuntu/pool/main/c/curl/curl_7.68.0-1ubuntu2.22_amd64.deb 暂时不能解析域名“cn.archive.ubuntu.com” 解决方法 sudo service network-manager stopsudo rm /var/lib/NetworkMana

ubuntu没有声音aplay -l找不到音效卡,unbuntu声卡驱动有问题,解决电脑没有声音

机子没有声音的,说最痛苦了,看个视频学习学习都难受,         折腾了这么久最后找到这篇帖子,希望对大家有用,个人感受是,ubuntu10.04版本系统的电脑无声问题跟电脑型号无关,因为我的一台HP笔记本,和多彩台式电脑,都是用此方法解决的,之前一直有去不同的主板商那里下驱动,可惜都不支持linux平台。 1.下载linux版本的官方驱动包  Realtek官网

再探旋转相机中的图像拼接问题

Homography 知多少? https://blog.csdn.net/heyijia0327/article/details/53782094 在ORB-SLAM初始化的时候,作者提到,如果场景是平面,或者近似平面,或者低视差时,我们能应用单应性矩阵(homography),这三种情形在我应用SVO的过程中颇有同感,打破了我对HH矩阵的固有映像,即只能用于平面或近似平面。 在学SLAM