• 多线程学习之三生产者消费者模式Guarded Suspension


    Guarded Suspension【生产消费者模式】

    一:guarded suspension的参与者
    --->guardedObject(被防卫)参与者
                    1.1该参与者拥有一个被防卫的方法(getRequest),如果警戒条件达成,则执行。警戒条件不达成,则线程进入wait set
                    1.2该参与者还拥有一个改变参与者状态的方法(putRequest)。参与者的状态影响着警戒条件的是否达成。

    --->该模式的角色:生产端线程,消费端线程,传递数据的摇篮(被防卫的参与者)
           

    二:guarded suspension模式什么时候使用
    --->适合交易系统使用。客户端下单,服务端处理订单。高并发,大量数据处理的模式,增强服务的吞吐量
       

    三:guarded suspension思考
    --->与该模式共通的三个特征
                    3.1:有循环存在
                    3.2:有条件测试
                    3.3:有因某种原因的等待

    ---> guarded wait 被阻断而等待
            等待端范例:
            while(条件){
                    wait();
            }
            唤醒端范例:
                    条件=true
                    notifyAll();
    ---> busy wait 忙碌地等待
            yield,尽可能把优先级交给其他线程,那个线程调用此方法,那个线程暂时一次让出CPU调度权。至于能否暂停,实际看cpu是否去掉别的线程。我主动 放弃一次,至于cpu走不走,看cpu的。yield不会解除锁定,所以这段代码不可写在snychronized里。而ready字段必须声明成 volatile
            等待端范例:
            while(ready){
                    Thead.yield();
            }
            唤醒端范例:
            ready=true

    ---> spin lock 旋转而锁定
            旋转而锁定的意思,表现出条件成立前while循环不断"旋转"的样子,spin lock有时意思与guarded wait相同,有时则与busy wait相同。另外,有时候则是指一开始使用busy wait ,之后再切换成guarded wait方式。另外有些硬件实现的同步机制

    --->polling
    " 进行舆论调查"的意思,反复检查某个事件是否发生,当发生时就进行对应的处理。

    请求实体类

     1 /**
     2  * 
     3  */
     4 package com.benxq.thread4;
     5 
     6 /**
     7  * 模拟请求实体
     8  * Created by qucf on 2015年10月22日. 
     9  */
    10 public class RequestEntity {
    11 
    12     //请求人的名称
    13     private String name;
    14     
    15     //线程的名称
    16     private String clientThreadName;
    17 
    18     
    19     public RequestEntity() {
    20         super();
    21     }
    22 
    23     /**
    24      * @param name
    25      * @param clientThreadName
    26      */
    27     public RequestEntity(String name, String clientThreadName) {
    28         super();
    29         this.name = name;
    30         this.clientThreadName = clientThreadName;
    31     }
    32 
    33     public String getName() {
    34         return name;
    35     }
    36 
    37     public void setName(String name) {
    38         this.name = name;
    39     }
    40 
    41     public String getClientThreadName() {
    42         return clientThreadName;
    43     }
    44 
    45     public void setClientThreadName(String clientThreadName) {
    46         this.clientThreadName = clientThreadName;
    47     }
    48     
    49     @Override
    50     public String toString() {
    51         return "生产者:"+clientThreadName+"生产者生产的产品"+name+"被消费";
    52     }
    53 }
    View Code

    请求实体队列类

     1 /**
     2  * 
     3  */
     4 package com.benxq.thread4;
     5 
     6 import java.util.LinkedList;
     7 
     8 /**
     9  * 模拟请求队列
    10  * Created by qucf on 2015年10月22日. 
    11  */
    12 public class RequestQueue {
    13 
    14     //模拟队列容器
    15     private LinkedList<RequestEntity> list=new LinkedList<RequestEntity>();
    16     
    17     //从队列中取出数据
    18     public synchronized RequestEntity getRequestEntity(){
    19         //当容器中的数据为0时进入等待状态
    20         while(list.size()<=0){
    21             try {
    22                 wait();
    23             } catch (InterruptedException e) {
    24                 // TODO Auto-generated catch block
    25                 e.printStackTrace();
    26             }
    27         }
    28         //如果不为空,返回第一个请求,并从集合中删除该请求
    29         return list.removeFirst();
    30     }
    31     
    32     //往队列中加入数据
    33     public synchronized void putRequestEntity(RequestEntity entity){
    34         //将加入的数据加入队列尾部
    35         list.addLast(entity);
    36         //唤醒所有的线程
    37         notifyAll();
    38     }
    39     
    40 }
    View Code

    生产线程

     1 /**
     2  * 
     3  */
     4 package com.benxq.thread4;
     5 
     6 import java.util.Random;
     7 
     8 /**
     9  * 模拟请求线程
    10  * Created by qucf on 2015年10月22日. 
    11  */
    12 public class ClientThread implements Runnable{
    13 
    14     //存放请求的队列
    15     private RequestQueue queue;
    16     
    17     //随机数
    18     private Random random;
    19     
    20     //线程名称
    21     private String name;
    22 
    23     
    24 
    25     /**
    26      * @param queue
    27      * @param random
    28      * @param name
    29      */
    30     public ClientThread(RequestQueue queue, Random random, String name) {
    31         super();
    32         this.queue = queue;
    33         this.random = random;
    34         this.name = name;
    35     }
    36 
    37 
    38 
    39     @Override
    40     public void run() {
    41 
    42         for (int i = 0; i < 5; i++) {
    43             //生成一个请求
    44             RequestEntity entity=new RequestEntity("No"+i, name);
    45             
    46             //将请求放入到队列中
    47             queue.putRequestEntity(entity);
    48             
    49             //让线程休息几秒
    50             try {
    51                 Thread.sleep(1000);
    52             } catch (InterruptedException e) {
    53                 // TODO Auto-generated catch block
    54                 e.printStackTrace();
    55             }
    56         }
    57     }
    58 }
    View Code

    消费线程

     1 /**
     2  * 
     3  */
     4 package com.benxq.thread4;
     5 
     6 import java.util.Random;
     7 
     8 /**
     9  * 消费线程
    10  * Created by qucf on 2015年10月22日. 
    11  */
    12 public class ServiceThread implements Runnable{
    13 
    14     //持有线程的队列
    15     private RequestQueue queue;
    16     //随机数
    17     private Random random;
    18     //线程名
    19     private String name;
    20     
    21     @Override
    22     public void run() {
    23         while(true){
    24             RequestEntity entiry=queue.getRequestEntity();
    25             System.out.println("消费线程"+name+"----->"+entiry.toString());
    26             try {
    27                 Thread.sleep(random.nextInt(random.nextInt(1000)));
    28             } catch (InterruptedException e) {
    29                 // TODO Auto-generated catch block
    30                 e.printStackTrace();
    31             }
    32         }
    33     }
    34 
    35     /**
    36      * @param queue
    37      * @param random
    38      * @param name
    39      */
    40     public ServiceThread(RequestQueue queue, Random random, String name) {
    41         super();
    42         this.queue = queue;
    43         this.random = random;
    44         this.name = name;
    45     }
    46 
    47     
    48 }
    View Code

    主线程

     1 /**
     2  * 
     3  */
     4 package com.benxq.thread4;
     5 
     6 import java.util.Random;
     7 
     8 /**
     9  * 主线程
    10  * Created by qucf on 2015年10月22日. 
    11  */
    12 public class Test {
    13 
    14     
    15     public static void main(String[] args) {
    16         //声明一个队列
    17         RequestQueue queue=new RequestQueue();
    18         
    19         //生产者线程
    20         Thread sc1=new Thread(new ClientThread(queue, new Random(), "QQ客户端"));
    21         Thread sc2=new Thread(new ClientThread(queue, new Random(), "ALIBABA客户端"));
    22         
    23         //消费者线程
    24         Thread xf1=new Thread(new ServiceThread(queue, new Random(), "渠道1"));
    25         Thread xf2=new Thread(new ServiceThread(queue, new Random(), "渠道2"));
    26         Thread xf3=new Thread(new ServiceThread(queue, new Random(), "渠道3"));
    27         
    28         //开启线程
    29         sc1.start();
    30         sc2.start();
    31         
    32         xf1.start();
    33         xf2.start();
    34         xf3.start();
    35     }
    36 }
    View Code
  • 相关阅读:
    JS 基于面向对象的 轮播图1
    JS 原型继承的几种方法
    angularJs 自定义服务 provide 与 factory 的区别
    C# 调用JS Eval,高效率
    Linq表连接大全(INNER JOIN、LEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN、CROSS JOIN)
    C# LINQ干掉for循环
    C# 彻底搞懂async/await
    .NET中的异步编程——动机和单元测试
    .NET中的异步编程——常见的错误和最佳实践
    C# 实用代码段
  • 原文地址:https://www.cnblogs.com/quchengfeng/p/4901552.html
Copyright © 2020-2023  润新知