文档章节

多线程模式(2):Guarded Suspension模式

小七酱
 小七酱
发布于 2015/07/24 10:18
字数 788
阅读 11
收藏 0
  1. 封装请求类

package com.xqi.g_s;

import com.xqi.f.Data;

/**
 * 请求封装
 * 
 * @author mike <br>
 *         2015年7月23日
 */
public class Request {

    private String name;//请求名称

    private Data response;//请求返回数据

    public synchronized Data getResponse() {
        return response;
    }

    public void setResponse(Data response) {
        this.response = response;
    }

    public Request(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "[ Reqeust :" + name + "]";
    }

}

2. 创建请求队列

package com.xqi.g_s;

import java.util.LinkedList;

/**
 * 请求队列
 * 
 * @author mike <br>
 *         2015年7月23日
 */
public class RequestQueue {
    // 定义存储请求的列表
    private LinkedList queue = new LinkedList();

    // 获取一个请求
    public synchronized Request getRequest() {
        while (queue.size() == 0) {
            try {
                wait();// 让这个对象的线程挂起(等待),在添加的请求的时候唤醒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return (Request) queue.remove();// 调用remove()的时候,会返回对象
    }

    public synchronized void addRequest(Request request) {
        queue.add(request);
        notifyAll();// 因为这个对象的线程已经waiting了,需要唤醒它来处理这个请求
    }

}

3. 服务器处理的线程

package com.xqi.g_s;

import com.xqi.f.FutureData;
import com.xqi.f.RealData;

/**
 * 服务器线程
 * 
 * @author mike <br>
 *         2015年7月23日
 */
public class ServerThread extends Thread {

    private RequestQueue queue;

    public ServerThread(RequestQueue queue, String name) {
        super(name);
        this.queue = queue;
    }

    @Override
    public void run() {
        while (true) {
            final Request request = queue.getRequest();
            final FutureData future = (FutureData) request.getResponse();
            RealData realData = new RealData(request.getName());
            // 通知future处理
            future.setRealData(realData);
            System.out.println("ServerThread Name is: "+Thread.currentThread().getName() + " handles " + request);
        }
    }

}

4. 模拟客户端线程

package com.xqi.g_s;

import java.util.ArrayList;
import java.util.List;

import com.xqi.f.FutureData;
import com.xqi.f.RealData;

/**
 * 客户端线程
 * 
 * @author mike <br>
 *         2015年7月23日
 */
public class ClientThread extends Thread {

    private RequestQueue queue;
    
    private List<Request> myRequest = new ArrayList<Request>();
    

    public ClientThread(RequestQueue queue, String name) {
        super(name);
        this.queue = queue;
    }

    @Override
    public void run() {
        //处理请求
        for (int i = 0; i < 10; i++) {
            Request req = new Request("RquestId: " + i + " Thread_Name: " + Thread.currentThread().getName());
            System.out.println("ClientThread Name is: "+Thread.currentThread().getName() + " requests " + req);
            //设置需要返回的数据
            FutureData future =new FutureData();
            future.setRealData(new RealData(i+""));
            req.setResponse(future);
            //发送请求
            queue.addRequest(req);
            myRequest.add(req);
            
            try {
                Thread.sleep(1000); //模拟请求间隔耗时
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
//            System.out.println(Thread.currentThread().getName() + " handles " + req);
        }
        // 打印返回的结果
        for (Request r : myRequest) {
            System.out.println("ClientThread Name is :"+Thread.currentThread().getName()+" Response is:"+r.getResponse().getResult());
        }
        
//        System.out.println(Thread.currentThread().getName() +" request end");
        
    }

}


5. 测试

package com.xqi.g_s;

/**
 * 测试主类
 * 
 * @author mike <br>
 *         2015年7月24日
 */
public class GSTest {

    public static void main(String[] args) {

        RequestQueue queue = new RequestQueue();
        // 2x1的服务器处理
        for (int i = 0; i < 2; i++) {
            new ServerThread(queue, "ServerThread" + i).start();
        }
        // 5x10的客户端请求
        for (int i = 0; i < 5; i++) {
            new ClientThread(queue, "ClientThread" + i).start();
        }

    }

}

6. 返回

                  .......................................................
ClientThread Name is: ClientThread1 requests [ Reqeust :RquestId: 0 Thread_Name: ClientThread1]
ClientThread Name is: ClientThread0 requests [ Reqeust :RquestId: 0 Thread_Name: ClientThread0]
ClientThread Name is: ClientThread4 requests [ Reqeust :RquestId: 0 Thread_Name: ClientThread4]
ClientThread Name is: ClientThread3 requests [ Reqeust :RquestId: 0 Thread_Name: ClientThread3]
ClientThread Name is: ClientThread2 requests [ Reqeust :RquestId: 0 Thread_Name: ClientThread2]
ServerThread Name is: ServerThread0 handles [ Reqeust :RquestId: 0 Thread_Name: ClientThread2]
ServerThread Name is: ServerThread1 handles [ Reqeust :RquestId: 0 Thread_Name: ClientThread1]
ServerThread Name is: ServerThread0 handles [ Reqeust :RquestId: 0 Thread_Name: ClientThread4]
ServerThread Name is: ServerThread1 handles [ Reqeust :RquestId: 0 Thread_Name: ClientThread3]
ServerThread Name is: ServerThread0 handles [ Reqeust :RquestId: 0 Thread_Name: ClientThread0]
                 .......................................................

ClientThread Name is :ClientThread3 Response is:0
ClientThread Name is :ClientThread3 Response is:1
ClientThread Name is :ClientThread3 Response is:2
ClientThread Name is :ClientThread3 Response is:3
ClientThread Name is :ClientThread3 Response is:4
ClientThread Name is :ClientThread3 Response is:5
ClientThread Name is :ClientThread3 Response is:6
ClientThread Name is :ClientThread3 Response is:7
ClientThread Name is :ClientThread3 Response is:8
ClientThread Name is :ClientThread3 Response is:9
                 .......................................................


PS: 这个Demo要Future模式来结合处理!

一开始,我很是不理解wait和notifyAll,然而,看看线程基础和实例中多试验几次,也就明白了!





© 著作权归作者所有

小七酱
粉丝 1
博文 30
码字总数 17079
作品 0
武汉
程序员
私信 提问
Java多线程16 Guarded Suspension设计模式

Java多线程目录 Guarded Suspension意为保护暂停,其核心思想是仅当服务进程准备好时,才提供服务。设想一种场景,服务器可能会在很短时间内承受大量的客户端请求,客户端请求的数量可能超过...

香沙小熊
01/26
0
0
多线程程序设计学习(4)guarded suspension模式

Guarded Suspension【生产消费者模式】 一:guarded suspension的参与者 --->guardedObject(被防卫)参与者 1.1该参与者拥有一个被防卫的方法(getRequest),如果警戒条件达成,则执行。警戒条...

无信不立
2015/07/18
0
0
并发编程 - Guarded Suspension模式

Guarded Suspension意为保护暂停,其核心思想是仅当服务进程准备好时,才提供服务。设想一种场景,服务器可能在很短时间内承受大量的客户请求,客户端请求的数量可能超过服务器本身的处理能力...

cosco
2016/05/09
77
3
Guarded Suspension

Guarded Suspension 当线程需要一些资源准备的时候才可以运行的时候就最好使用Guarded Suspension,对使用资源的部分使用保卫空间,不满足就wait(),对补充资源的地方使用notifyAll/notif...

年少爱追梦
2016/04/19
8
0
多线程程序设计学习(5)balking模式和timed模式

Balking【返回模式】timed【超时模式】 一:balking pattern的参与者 --->GuardedObject(被警戒的对象) --->该模式的角色:模拟修改警戒对象的线程,当警戒条件达到执行具体操作的线程,参与者...

无信不立
2015/07/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

将博客搬至CSDN

https://blog.csdn.net/qq_38157006

Marhal
23分钟前
1
0
unicode Java中求字符串长度length()和codePointCount()的区别

在计算字符串长度时,Java的两种方法length()和codePointCount()一度让我困惑,运行书上例子得到的长度值是相等的,那为什么要设定两个方法呢? 对于普通字符串,这两种方法得到的值是一样的...

泉天下
23分钟前
2
0
uin-app 一、学习理由

选择uni-app 理由 别人的理由 1. 5+ 有HTML5+和Native.js技术,HTML5+包含常用的跨平台的几百个API,能满足常规开发需求,而Native.js把40w原生api映 射成js对象,这样js可以直接调原生。HTM...

轻轻的往前走
25分钟前
1
0
方括号及其在命令行中的不同用法介绍

通配 方括号最简单的用法就是通配。你可能在知道“ Globbing”这个概念之前就已经通过通配来匹配内容了,列出具有相同特征的多个文件就是一个很常见的场景,例如列出所有 JPEG 文件: ls *.j...

Linux就该这么学
31分钟前
2
0
vecty 基础

gopherjs 是把 go 编译为 js 的工具。 vecty 是基于 gopherjs 的一种类似 React 的开发框架。 安装 gopherjs 和 vecty go get -u github.com/gopherjs/gopherjsgo get -u github.com/gopher......

electricface
32分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部