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

  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,然而,看看线程基础和实例中多试验几次,也就明白了!





你可能感兴趣的:(多线程模式(2):Guarded Suspension模式)