当前位置: 首页 > wzjs >正文

北京网站设计建设wordpress定制分类

北京网站设计建设,wordpress定制分类,lamp网站开发经验,城乡建设部官方网站3.生产者消费者 3.1生产者和消费者模式概述【应用】 概述 生产者消费者模式是一个十分经典的多线程协作的模式,弄懂生产者消费者问题能够让我们对多线程编程的理解更加深刻。 所谓生产者消费者问题,实际上主要是包含了两类线程: 一类是生产者…

3.生产者消费者

3.1生产者和消费者模式概述【应用】

  • 概述

    生产者消费者模式是一个十分经典的多线程协作的模式,弄懂生产者消费者问题能够让我们对多线程编程的理解更加深刻。

    所谓生产者消费者问题,实际上主要是包含了两类线程:

    一类是生产者线程用于生产数据

    一类是消费者线程用于消费数据

    为了解耦生产者和消费者的关系,通常会采用共享的数据区域,就像是一个仓库

    生产者生产数据之后直接放置在共享数据区中,并不需要关心消费者的行为

    消费者只需要从共享数据区中去获取数据,并不需要关心生产者的行为

  • Object类的等待和唤醒方法

    方法名说明
    void wait()导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法
    void notify()唤醒正在等待对象监视器的单个线程
    void notifyAll()唤醒正在等待对象监视器的所有线程

3.2生产者和消费者案例【应用】

  • 案例需求

    • 桌子类(Desk):定义表示包子数量的变量,定义锁对象变量,定义标记桌子上有无包子的变量

    • 生产者类(Cooker):实现Runnable接口,重写run()方法,设置线程任务

      1.判断是否有包子,决定当前线程是否执行

      2.如果有包子,就进入等待状态,如果没有包子,继续执行,生产包子

      3.生产包子之后,更新桌子上包子状态,唤醒消费者消费包子

    • 消费者类(Foodie):实现Runnable接口,重写run()方法,设置线程任务

      1.判断是否有包子,决定当前线程是否执行

      2.如果没有包子,就进入等待状态,如果有包子,就消费包子

      3.消费包子后,更新桌子上包子状态,唤醒生产者生产包子

    • 测试类(Demo):里面有main方法,main方法中的代码步骤如下

      创建生产者线程和消费者线程对象

      分别开启两个线程

  • 代码实现

    public class Desk {
    ​//定义一个标记//true 就表示桌子上有汉堡包的,此时允许吃货执行//false 就表示桌子上没有汉堡包的,此时允许厨师执行public static boolean flag = false;
    ​//汉堡包的总数量public static int count = 10;
    ​//锁对象public static final Object lock = new Object();
    }
    ​
    public class Cooker extends Thread {
    //    生产者步骤:
    //            1,判断桌子上是否有汉堡包
    //    如果有就等待,如果没有才生产。
    //            2,把汉堡包放在桌子上。
    //            3,叫醒等待的消费者开吃。@Overridepublic void run() {while(true){synchronized (Desk.lock){if(Desk.count == 0){break;}else{if(!Desk.flag){//生产System.out.println("厨师正在生产汉堡包");Desk.flag = true;Desk.lock.notifyAll();}else{try {Desk.lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}}
    }
    ​
    public class Foodie extends Thread {@Overridepublic void run() {
    //        1,判断桌子上是否有汉堡包。
    //        2,如果没有就等待。
    //        3,如果有就开吃
    //        4,吃完之后,桌子上的汉堡包就没有了
    //                叫醒等待的生产者继续生产
    //        汉堡包的总数量减一
    ​//套路://1. while(true)死循环//2. synchronized 锁,锁对象要唯一//3. 判断,共享数据是否结束. 结束//4. 判断,共享数据是否结束. 没有结束while(true){synchronized (Desk.lock){if(Desk.count == 0){break;}else{if(Desk.flag){//有System.out.println("吃货在吃汉堡包");Desk.flag = false;Desk.lock.notifyAll();Desk.count--;}else{//没有就等待//使用什么对象当做锁,那么就必须用这个对象去调用等待和唤醒的方法.try {Desk.lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}
    ​}
    }
    ​
    public class Demo {public static void main(String[] args) {/*消费者步骤:1,判断桌子上是否有汉堡包。2,如果没有就等待。3,如果有就开吃4,吃完之后,桌子上的汉堡包就没有了叫醒等待的生产者继续生产汉堡包的总数量减一*/
    ​/*生产者步骤:1,判断桌子上是否有汉堡包如果有就等待,如果没有才生产。2,把汉堡包放在桌子上。3,叫醒等待的消费者开吃。*/
    ​Foodie f = new Foodie();Cooker c = new Cooker();
    ​f.start();c.start();
    ​}
    }

3.3生产者和消费者案例优化【应用】

  • 需求

    • 将Desk类中的变量,采用面向对象的方式封装起来

    • 生产者和消费者类中构造方法接收Desk类对象,之后在run方法中进行使用

    • 创建生产者和消费者线程对象,构造方法中传入Desk类对象

    • 开启两个线程

  • 代码实现

    public class Desk {
    ​//定义一个标记//true 就表示桌子上有汉堡包的,此时允许吃货执行//false 就表示桌子上没有汉堡包的,此时允许厨师执行//public static boolean flag = false;private boolean flag;
    ​//汉堡包的总数量//public static int count = 10;//以后我们在使用这种必须有默认值的变量// private int count = 10;private int count;
    ​//锁对象//public static final Object lock = new Object();private final Object lock = new Object();
    ​public Desk() {this(false,10); // 在空参内部调用带参,对成员变量进行赋值,之后就可以直接使用成员变量了}
    ​public Desk(boolean flag, int count) {this.flag = flag;this.count = count;}
    ​public boolean isFlag() {return flag;}
    ​public void setFlag(boolean flag) {this.flag = flag;}
    ​public int getCount() {return count;}
    ​public void setCount(int count) {this.count = count;}
    ​public Object getLock() {return lock;}
    ​@Overridepublic String toString() {return "Desk{" +"flag=" + flag +", count=" + count +", lock=" + lock +'}';}
    }
    ​
    public class Cooker extends Thread {
    ​private Desk desk;
    ​public Cooker(Desk desk) {this.desk = desk;}
    //    生产者步骤:
    //            1,判断桌子上是否有汉堡包
    //    如果有就等待,如果没有才生产。
    //            2,把汉堡包放在桌子上。
    //            3,叫醒等待的消费者开吃。
    ​@Overridepublic void run() {while(true){synchronized (desk.getLock()){if(desk.getCount() == 0){break;}else{//System.out.println("验证一下是否执行了");if(!desk.isFlag()){//生产System.out.println("厨师正在生产汉堡包");desk.setFlag(true);desk.getLock().notifyAll();}else{try {desk.getLock().wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}}
    }
    ​
    public class Foodie extends Thread {private Desk desk;
    ​public Foodie(Desk desk) {this.desk = desk;}
    ​@Overridepublic void run() {
    //        1,判断桌子上是否有汉堡包。
    //        2,如果没有就等待。
    //        3,如果有就开吃
    //        4,吃完之后,桌子上的汉堡包就没有了
    //                叫醒等待的生产者继续生产
    //        汉堡包的总数量减一
    ​//套路://1. while(true)死循环//2. synchronized 锁,锁对象要唯一//3. 判断,共享数据是否结束. 结束//4. 判断,共享数据是否结束. 没有结束while(true){synchronized (desk.getLock()){if(desk.getCount() == 0){break;}else{//System.out.println("验证一下是否执行了");if(desk.isFlag()){//有System.out.println("吃货在吃汉堡包");desk.setFlag(false);desk.getLock().notifyAll();desk.setCount(desk.getCount() - 1);}else{//没有就等待//使用什么对象当做锁,那么就必须用这个对象去调用等待和唤醒的方法.try {desk.getLock().wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}
    ​}
    }
    ​
    public class Demo {public static void main(String[] args) {/*消费者步骤:1,判断桌子上是否有汉堡包。2,如果没有就等待。3,如果有就开吃4,吃完之后,桌子上的汉堡包就没有了叫醒等待的生产者继续生产汉堡包的总数量减一*/
    ​/*生产者步骤:1,判断桌子上是否有汉堡包如果有就等待,如果没有才生产。2,把汉堡包放在桌子上。3,叫醒等待的消费者开吃。*/
    ​Desk desk = new Desk();
    ​Foodie f = new Foodie(desk);Cooker c = new Cooker(desk);
    ​f.start();c.start();
    ​}
    }

3.4阻塞队列基本使用【理解】

  • 阻塞队列继承结构

  • 常见BlockingQueue:

    ArrayBlockingQueue: 底层是数组,有界

    LinkedBlockingQueue: 底层是链表,无界.但不是真正的无界,最大为int的最大值

  • BlockingQueue的核心方法:

    put(anObject): 将参数放入队列,如果放不进去会阻塞

    take(): 取出第一个数据,取不到会阻塞

  • 代码示例

    public class Demo02 {public static void main(String[] args) throws Exception {// 创建阻塞队列的对象,容量为 1ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(1);
    ​// 存储元素arrayBlockingQueue.put("汉堡包");
    ​// 取元素System.out.println(arrayBlockingQueue.take());System.out.println(arrayBlockingQueue.take()); // 取不到会阻塞
    ​System.out.println("程序结束了");}
    }

3.5阻塞队列实现等待唤醒机制【理解】

  • 案例需求

    • 生产者类(Cooker):实现Runnable接口,重写run()方法,设置线程任务

      1.构造方法中接收一个阻塞队列对象

      2.在run方法中循环向阻塞队列中添加包子

      3.打印添加结果

    • 消费者类(Foodie):实现Runnable接口,重写run()方法,设置线程任务

      1.构造方法中接收一个阻塞队列对象

      2.在run方法中循环获取阻塞队列中的包子

      3.打印获取结果

    • 测试类(Demo):里面有main方法,main方法中的代码步骤如下

      创建阻塞队列对象

      创建生产者线程和消费者线程对象,构造方法中传入阻塞队列对象

      分别开启两个线程

  • 代码实现

    public class Cooker extends Thread {
    ​private ArrayBlockingQueue<String> bd;
    ​public Cooker(ArrayBlockingQueue<String> bd) {this.bd = bd;}
    //    生产者步骤:
    //            1,判断桌子上是否有汉堡包
    //    如果有就等待,如果没有才生产。
    //            2,把汉堡包放在桌子上。
    //            3,叫醒等待的消费者开吃。
    ​@Overridepublic void run() {while (true) {try {bd.put("汉堡包");System.out.println("厨师放入一个汉堡包");} catch (InterruptedException e) {e.printStackTrace();}}}
    }
    ​
    public class Foodie extends Thread {private ArrayBlockingQueue<String> bd;
    ​public Foodie(ArrayBlockingQueue<String> bd) {this.bd = bd;}
    ​@Overridepublic void run() {
    //        1,判断桌子上是否有汉堡包。
    //        2,如果没有就等待。
    //        3,如果有就开吃
    //        4,吃完之后,桌子上的汉堡包就没有了
    //                叫醒等待的生产者继续生产
    //        汉堡包的总数量减一
    ​//套路://1. while(true)死循环//2. synchronized 锁,锁对象要唯一//3. 判断,共享数据是否结束. 结束//4. 判断,共享数据是否结束. 没有结束while (true) {try {String take = bd.take();System.out.println("吃货将" + take + "拿出来吃了");} catch (InterruptedException e) {e.printStackTrace();}}
    ​}
    }
    ​
    public class Demo {public static void main(String[] args) {ArrayBlockingQueue<String> bd = new ArrayBlockingQueue<>(1);
    ​Foodie f = new Foodie(bd);Cooker c = new Cooker(bd);
    ​f.start();c.start();}
    }


文章转载自:

http://qft3eDON.bxqpL.cn
http://uhF3cpJh.bxqpL.cn
http://NISC9VPo.bxqpL.cn
http://M6hR7MQt.bxqpL.cn
http://Qlql834b.bxqpL.cn
http://m8gXaRwP.bxqpL.cn
http://jGbAKkdn.bxqpL.cn
http://98zVDkqt.bxqpL.cn
http://lyaaR5G3.bxqpL.cn
http://35GUJbXO.bxqpL.cn
http://1llI704l.bxqpL.cn
http://xnlpOqpF.bxqpL.cn
http://9zsiyTYD.bxqpL.cn
http://fqdaOZ5K.bxqpL.cn
http://usDhtFrd.bxqpL.cn
http://I0NMik6j.bxqpL.cn
http://x1m0RUDa.bxqpL.cn
http://8KzW7fKJ.bxqpL.cn
http://ry5Ooqhy.bxqpL.cn
http://d7UKle3S.bxqpL.cn
http://zX86Qz9R.bxqpL.cn
http://o3sfD9LM.bxqpL.cn
http://zmsBS2cn.bxqpL.cn
http://skIzJbg0.bxqpL.cn
http://5oVp2sMv.bxqpL.cn
http://ncdBmQvX.bxqpL.cn
http://XqpQXUM9.bxqpL.cn
http://dy9yUnPo.bxqpL.cn
http://rYnv5AzS.bxqpL.cn
http://cPCD0hzt.bxqpL.cn
http://www.dtcms.com/wzjs/630665.html

相关文章:

  • 别人是怎么建设网站的铜川建设网站
  • 环球资源网站什么时候做的php中英文网站
  • 创建视频网站免费注册机械加工网报价
  • 温州高端网站定制网站布局设计步骤
  • 上传到网站的根目录中多用户商城app
  • 百度产品有哪些乌市seo网络营销流程
  • 网站建设费 科研 类图书馆理论与建设网站
  • 深圳建设网站哪家最好做网站一般用什么服务器
  • js 网站首页下拉广告靖江市住房和城乡建设局的网站
  • 苏州网站建设公司有哪些建设020网站需要多少钱
  • 烟台网站seo服务短视频营销方式
  • 帮别人做网站 开票内容是什么企业网站开发的感想
  • 吉林分销网站建设东乌珠穆沁旗网站建设
  • 古镇 网站建设如何设计产品网站建设
  • iis7.0网站错误代码解决重庆旅游网站建设
  • 海淀网站建设龙岩一直免费的服务器下载
  • 淘宝联盟交钱建设网站润商网站建设
  • 做网站应该用多少分辨率化工网站建站模板下载
  • 网站主机购买东莞建设网站软件
  • 旅游网站设计的建设原则绿色长春app
  • 做外贸怎么登陆国外网站12306网站建设投标书
  • 如何在网站中做公示信息北京朝阳区最好的小区
  • 大型综合新闻门户网站织梦模板wordpress强大吗
  • 小公司让我用织梦做网站卖网站怎样做
  • 做网站什么配置够用专业北京网站建设公司哪家好
  • 外国人做中国英语视频网站淘宝客网站可以做分销吗
  • 如何防止别人攻击自己的网站jsp门户网站开发
  • 网页调用 wordpress 图片编辑器中国十大seo
  • 广州网站制作选哪家中国联通与腾讯设立混改合营企业
  • 关于网站建设实训报告46设计网站官网