Producer-Consumer【生产消费者模式】
一:Producer-Consumer pattern的参与者
--->产品(蛋糕)
--->通道(传递蛋糕的桌子)
--->生产者线程(制造蛋糕的线程)
--->消费者线程(吃掉蛋糕的线程)

二:Producer-Consumer pattern模式什么时候使用
--->大量生产+大量消费的模式

三:Producer-Consumer pattern思考
--->【生产消费者模式】,肩负保护数据安全性使命的是通道参与者。通道参与者参与进行线程间的共享互斥,让生产着能正确将数据传递到消费者手中。
--->通道(桌子)的put和take方法都使用了【独木桥模式】,而生产者和消费者都不想依赖table类的详细实现,也就说,生产者不必理会其他线程,只管生产并put,同样消费者也不必理会其他线程,只管take就好。而线程的共享互斥,synchronized,wati,notifyAll这些考虑的多线程操作的代码,全都隐藏在通道table类里。提高了table的复用性。

--->生产者消费者模式,存在两方处理速率不同的话,必然造成一方等待,或占用通道大量内存的问题。

--->多线程合作的口决
        线程的合作要想:放在中间的东西
        线程的互斥要想:应该保护的东西

--->多生产者对单一消费者,如果情况合理,一方可以不用考虑互斥,就不用加锁,提升性能。

四进阶说明
--->习惯编写java多线程。当所调用的方法抛出,或内部抓住异常:InterruptedException.
        ==>通常传递给我们两个信息。(1)这是‘需要花点时间’的方法(2)这是‘可以取消’的方法
        ==>告诉我们方法内部有这三个选手:java.lang.Object类里的wait方法        
                                                                                     java.lang.Thread类里的sleep方法
                                                                                     java.lang.Thread类里的join方法
                
--->需要花点时间的方法
        wait==>执行wait方法的线程,进入wait set里休眠,等待notify,notifyAll唤醒。在休眠期间不会活动,因此需要花费时间。
        sleep==>执行sleep,会暂停执行参数内所设置的时间,这也是需要花费时间
        join==>会等待制定的线程结束为止。才执行本线程。也就是花费直到制定线程结束之前的这段时间

--->可以取消的方法。
        因为需要花费时间,会降低程序的响应性,所以我们会希望像下面这样可以在中途放弃(取消)执行这个方法
        1取消wait方法等待notify,notifyAll唤醒的操作
        2取消sleep方法等待设置长度时间的操作
        3取消join方法等待其他线程结束的操作

--->取消线程等待的详细解说
       (1) A线程的实例为athread,线程体内部执行Thread.sleep(1000)时,想取消其睡眠状态。则需要B线程中取消。
                --->在B线程中用athread.interrupt().
                --->则A线程终止睡眠,并抛出或被抓住InterruptedException
                --->这个时候A线程的catch块的代码,至关重要。
      (2) A线程的实例为athread,线程体内部执行wait()时,想取消等待notify,notifyAll唤醒的操作。则需要B线程中取消。
                --->在B线程体中用athread.interrupt().
                --->则A线程终止等待状态,并尝试重新获取锁定。
                --->获取锁定后,抛出或被抓住InterruptedException
                --->这个时候A线程的catch块的代码,至关重要。
      (3)A线程的实例为athread,线程体内部执行join(),想等待其他线程执行结束。则需要B线程中取消。
                 --->在B线程中用athread.interrupt().
                --->则A线程终止睡眠,并抛出或被抓住InterruptedException
                --->这个时候A线程的catch块的代码,至关重要。

--->线程对象.interrupt(),Thead.interrupted,线程对象.isinterrupted()区别
        ==>interrupt()让等待或休眠的线程变成中断状态,抛出异常
        ==>interrupted()检查线程的中断状态
                                        是中断状态,返回true,并将中断状态修改成非中断状态
                                        不是中断状态,返回false,不做任何操作
        ==>isinterrupted简单的检查线程是否为中断状态,是返回true,不是返回false,不做任何操作

Producer-Consumer案例
        三个生产蛋糕的线程,三个消费蛋糕的线程,一个传递蛋糕的桌子。

传递蛋糕的桌子

 package com.yeepay.sxf.thread5;
/**
* 在消费线程和生产线程中间起传递作用的桌子
* @author sxf
*
*/ public class Table {
//存放蛋糕的数组
private String[] cakes;
//下一个放蛋糕的位置
private int nextPut;
//下一个取蛋糕的位置
private int nextGet;
//蛋糕数组中蛋糕的数量
private int count;
//构造器
public Table (int count){
this.cakes=new String[count];
this.nextGet=0;
this.nextPut=0;
}
//存放蛋糕
public synchronized void putCakes(String cake) throws InterruptedException{
System.out.println("["+Thread.currentThread().getName()+"]put"+cake);
//警戒条件 如果桌子上蛋糕,慢了,就阻塞生产线程。
while (count>=cakes.length) {
wait();
}
//将蛋糕放入模拟队列
cakes[nextPut]=cake;
//算出下一个放蛋糕的位置
nextPut=(nextPut+1)%cakes.length;
//蛋糕数据量加1
count++;
//唤醒别的线程
notifyAll();
} //取蛋糕
public synchronized String takeCake() throws InterruptedException{
//判断桌子上是否有蛋糕,如果没有,阻塞线程
while (count<=0) {
wait();
}
//取出蛋糕
String cake=cakes[nextGet];
//计算出下一个取蛋糕的位置
nextGet=(nextGet+1)%cakes.length;
//蛋糕数量减一
count--;
//唤醒其他线程
notifyAll();
System.out.println("【"+Thread.currentThread().getName()+"】get"+cake);
return cake;
}
}

生产蛋糕的线程

 package com.yeepay.sxf.thread5;
/**
* 制造蛋糕线程
* @author sxf
*
*/
public class MakeCakeThread implements Runnable{
//存放蛋糕的桌子
private Table table; //构造器
public MakeCakeThread(Table table) {
this.table=table;
} @Override
public void run() {
while (true) {
for (int i = 0; i <100; i++) { try {
//生产蛋糕,并放入
table.putCakes(Thread.currentThread().getName()+"的蛋糕"+i);
//当前线程休息1秒钟 Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } } }

吃掉蛋糕的线程

 package com.yeepay.sxf.thread5;
/**
* 吃蛋糕的线程
* @author sxf
*
*/
public class EatCakeThread implements Runnable {
//桌子
private Table table;
//构造器
public EatCakeThread(Table table){
this.table=table;
}
/**
* 线程体
*/
@Override
public void run() {
while(true){
try {
String cake=table.takeCake();
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } }

测试类

 package com.yeepay.sxf.thread5;
/**
* 测试类
* @author sxf
*
*/
public class Test { public static void main(String[] args) {
//声明一张桌子
Table table=new Table(4);
//声明生产蛋糕的线程
Thread makeThread1=new Thread(new MakeCakeThread(table));
makeThread1.setName("尚晓飞师傅");
Thread makeThread2=new Thread(new MakeCakeThread(table));
makeThread2.setName("范林军师傅");
Thread makeThread3=new Thread(new MakeCakeThread(table));
makeThread3.setName("黄栓林师傅"); //声明吃蛋糕的线程
Thread eatThread1=new Thread(new EatCakeThread(table));
eatThread1.setName("顾客1");
Thread eatThread2=new Thread(new EatCakeThread(table));
eatThread2.setName("顾客2");
Thread eatThread3=new Thread(new EatCakeThread(table));
eatThread3.setName("顾客3"); //启动线程
makeThread1.start();
makeThread2.start();
makeThread3.start();
eatThread1.start();
eatThread2.start();
eatThread3.start(); }
}

测试结果:

[尚晓飞师傅]put尚晓飞师傅的蛋糕0
[范林军师傅]put范林军师傅的蛋糕0
【顾客1】get尚晓飞师傅的蛋糕0
【顾客2】get范林军师傅的蛋糕0
[黄栓林师傅]put黄栓林师傅的蛋糕0
【顾客3】get黄栓林师傅的蛋糕0
[尚晓飞师傅]put尚晓飞师傅的蛋糕1
【顾客3】get尚晓飞师傅的蛋糕1
[范林军师傅]put范林军师傅的蛋糕1
【顾客1】get范林军师傅的蛋糕1
[黄栓林师傅]put黄栓林师傅的蛋糕1
【顾客2】get黄栓林师傅的蛋糕1
[尚晓飞师傅]put尚晓飞师傅的蛋糕2

多线程程序设计学习(6)Producer-Consumer模式的更多相关文章

  1. 多线程程序设计学习(2)之single threaded execution pattern

    Single Threaded Execution Pattern[独木桥模式] 一:single threaded execution pattern的参与者--->SharedResourc ...

  2. 多线程程序设计学习(3)immutable pattern模式

    Immutable pattern[坚不可摧模式] 一:immutable pattern的参与者--->immutable(不变的)参与者        1.1:immutable参与者是一个 ...

  3. 多线程程序设计学习(5)balking模式和timed模式

    Balking[返回模式]timed[超时模式]一:balking pattern的参与者--->GuardedObject(被警戒的对象) --->该模式的角色:模拟修改警戒对象的线程, ...

  4. 多线程程序设计学习(4)guarded suspension模式

    Guarded Suspension[生产消费者模式] 一:guarded suspension的参与者--->guardedObject(被防卫)参与者                1.1该 ...

  5. 多线程程序设计学习(9)worker pattern模式

    Worker pattern[工作模式]一:Worker pattern的参与者--->Client(委托人线程)--->Channel(通道,里边有,存放请求的队列)--->Req ...

  6. 多线程程序设计学习(13)Active Object pattern

    Active Object[接收异步消息的对象] 一:Active Object的参与者--->客户端线程(发起某种操作请求处理)--->代理角色(工头)--->实际执行者(工人)- ...

  7. 多线程程序设计学习(12)Thread-soecific storage pattern

    Thread-Specific-Storage[线程保管箱] 一:Thread-Specific Storage的参与者--->记录日志的线程(ClientThread)--->负责获取不 ...

  8. 多线程程序设计学习(11)Two-phapse-Termination pattern

    Two-phapse-Termination[A终止B线程] 一:Two-phapse-Termination的参与者--->A线程--->B线程 二:Two-phapse-Termina ...

  9. 多线程程序设计学习(10)Future pattern

    Future pattern[订单取货模式] 一:Future pattern的参与者--->Client(客户需求)--->Host(蛋糕门店)--->Data(票据和蛋糕的接口) ...

随机推荐

  1. 关于帝国cms 列表页SEO优化的问题

    一般列表页面中,我们都需要带分页信息区分当前页号,为区分第一页,和第一页后的其他所有分页页面.我们推荐的做法为:第一页显示正常的标题,从第二页开始便显示xxxxx-第2页-xxxx网.做法是.修改帝国 ...

  2. JDBC 简介

    [摘要] 1) JDBC : (Java Database Connectivity ,java数据基础连接)是标准的Java 访问数据库的API.即Java数据库编程接口,是一组标准的Java语言中 ...

  3. 关于sqlmap无法打开的问题解决办法

    sqlmap无法打开这个问题困扰了我几天,今天才从一个论坛的视频教程里看到这个办法,有可能对其他有些情况依旧没用,但是希望和我一样状况的人看到这篇文章,能收到一些启发 我之前百度了很久,google了 ...

  4. 1042: [HAOI2008]硬币购物 - BZOJ

    Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法.Input 第一行 ...

  5. js注册登录审核

    <script type="text/javascript"> $(function(){ $("#sendSms").click(function ...

  6. linux netstat命令使用详解

    快速应用 netstat -lnp | more 显示监听的端口 简介 Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),mas ...

  7. EASYUI Dialog的基本使用

    1.基本使用 代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server&q ...

  8. Servlet课程0425(四) Servlet实现简单用户登录验证

    Login.java //登录界面 package com.tsinghua; import javax.servlet.http.*; import java.io.*; public class ...

  9. C#基础精华04(文件流,文件操作,File、Directory、Path,Directory)

    文件流 FileStream  可读可写  大文件  释放 StreamReader 读取   释放 StreamWriter 写入   释放 using 中释放 File 可读可写  小文件 操作文 ...

  10. POJ2524——Ubiquitous Religions

    Ubiquitous Religions Description There are so many different religions in the world today that it is ...