多线程模式之Guarded Suspension
    最近突然对java的多线程设计模式兴趣盎然,于是乎google了一大堆的文章,其中比较全面的当属台湾同仁良葛格學習筆記中的文章,但台湾之国文读来却是我最怕怕的近乎文言文的表述,这里一方面想将自己的学习心得记录一二,另一方面也希望能给同仁们一点启发。
    顾名思义,Guarded Suspension模式,主要就是守护一个线程,防止它挂起后变成死线程。那么它运行在什么样的场合呢?比如:考虑如果有这么一个聊天服务器,它可以处理来自多个客户端的消息(message),为了不丢失客户的消息,那么聊天服务器需要维护一个缓冲区,客户的这些消息会先储存至缓冲区中,而服务器会从缓冲区中取出这些消息并根据要求回送到各个客户端,如果缓冲区中没有请求时,则服务器就等待,直到被通知有新的请求存入缓冲区中,服务器再度进行请求的执行。
   下面我们通过java.rmi包来模拟这个过程,体验一下这个模式的核心理念:
  1.需要实现的远程接口方法,主要是发送消息和获取消息
 package patterns.guardedSuspension;
package patterns.guardedSuspension;
 import java.rmi.RemoteException;
import java.rmi.RemoteException;
 /**
/** * @author Jackie Xie
 * @author Jackie Xie * 需要的远程接口
 * 需要的远程接口 */
 */ public interface IRequestQueue extends java.rmi.Remote {
public interface IRequestQueue extends java.rmi.Remote { public void putMessage(String msg) throws RemoteException;
    public void putMessage(String msg) throws RemoteException; public String getMessage() throws RemoteException;
    public String getMessage() throws RemoteException; }
} 2.rmi服务器侧代码
 1 /**
/**
2 *
 * 
3 */
 */
4 package patterns.guardedSuspension;
package patterns.guardedSuspension;
5
6 import java.rmi.RemoteException;
import java.rmi.RemoteException;
7 import java.util.LinkedList;
import java.util.LinkedList;
8
9
10 /**
/**
11 * @author Jackie Xie
 * @author Jackie Xie
12 *
 *
13 */
 */
14 public class RequestQueue extends java.rmi.server.UnicastRemoteObject  implements IRequestQueue {
public class RequestQueue extends java.rmi.server.UnicastRemoteObject  implements IRequestQueue {
15
16 /**
    /**
17 *
     * 
18 */
     */
19 private static final long serialVersionUID = -4555943092230346255L;
    private static final long serialVersionUID = -4555943092230346255L;
20 private LinkedList<String> queue;
    private LinkedList<String> queue;
21 private String userName;
    private String userName;
22
23 public RequestQueue(String userName)throws Exception {
    public RequestQueue(String userName)throws Exception {
24 // TODO Auto-generated constructor stub
        // TODO Auto-generated constructor stub
25 this.queue = new java.util.LinkedList<String>();
        this.queue = new java.util.LinkedList<String>();
26 this.userName = userName;
        this.userName = userName;
27 }
    }
28
29 private boolean isStop;
    private boolean isStop;
30
31 public void setStop(boolean isStop) {
    public void setStop(boolean isStop) {
32 // TODO Auto-generated method stub
        // TODO Auto-generated method stub
33 this.isStop = isStop;
        this.isStop = isStop;
34 }
    }
35
36 public boolean isStop() {
    public boolean isStop() {
37 return isStop;
        return isStop;
38 }
    }
39
40 public synchronized void putMessage(String request)throws RemoteException {
    public synchronized void putMessage(String request)throws RemoteException {
41 // TODO Auto-generated method stub
        // TODO Auto-generated method stub
42 this.queue.addLast(userName+":"+request);
        this.queue.addLast(userName+":"+request);
43 notifyAll();
        notifyAll();
44 }
    }
45 public synchronized String getMessage() throws RemoteException{
    public synchronized String getMessage() throws RemoteException{
46 while (this.queue.size()<=0) {
        while (this.queue.size()<=0) {
47 try {
            try {
48 wait();
                wait();
49 } catch (Exception e) {
            } catch (Exception e) {
50 // TODO: handle exception
                // TODO: handle exception
51 throw new RuntimeException();
                throw new RuntimeException();
52 }
            }
53 
            
54 }
        }
55 return this.queue.removeFirst();
        return this.queue.removeFirst();
56 }
    }
57
58 
    
59 }
}
60
 3.服务器绑定及运行代码 /**
/**2
 *
 * 3
 */
 */4
 package patterns.guardedSuspension;
package patterns.guardedSuspension;5

6
 import java.rmi.RemoteException;
import java.rmi.RemoteException;7
 import java.util.LinkedList;
import java.util.LinkedList;8

9

10
 /**
/**11
 * @author Jackie Xie
 * @author Jackie Xie12
 *
 *13
 */
 */14
 public class RequestQueue extends java.rmi.server.UnicastRemoteObject  implements IRequestQueue {
public class RequestQueue extends java.rmi.server.UnicastRemoteObject  implements IRequestQueue {15

16
 /**
    /**17
 *
     * 18
 */
     */19
 private static final long serialVersionUID = -4555943092230346255L;
    private static final long serialVersionUID = -4555943092230346255L;20
 private LinkedList<String> queue;
    private LinkedList<String> queue;21
 private String userName;
    private String userName;22

23
 public RequestQueue(String userName)throws Exception {
    public RequestQueue(String userName)throws Exception {24
 // TODO Auto-generated constructor stub
        // TODO Auto-generated constructor stub25
 this.queue = new java.util.LinkedList<String>();
        this.queue = new java.util.LinkedList<String>();26
 this.userName = userName;
        this.userName = userName;27
 }
    }28

29
 private boolean isStop;
    private boolean isStop;30

31
 public void setStop(boolean isStop) {
    public void setStop(boolean isStop) {32
 // TODO Auto-generated method stub
        // TODO Auto-generated method stub33
 this.isStop = isStop;
        this.isStop = isStop;34
 }
    }35

36
 public boolean isStop() {
    public boolean isStop() {37
 return isStop;
        return isStop;38
 }
    }39

40
 public synchronized void putMessage(String request)throws RemoteException {
    public synchronized void putMessage(String request)throws RemoteException {41
 // TODO Auto-generated method stub
        // TODO Auto-generated method stub42
 this.queue.addLast(userName+":"+request);
        this.queue.addLast(userName+":"+request);43
 notifyAll();
        notifyAll();44
 }
    }45
 public synchronized String getMessage() throws RemoteException{
    public synchronized String getMessage() throws RemoteException{46
 while (this.queue.size()<=0) {
        while (this.queue.size()<=0) {47
 try {
            try {48
 wait();
                wait();49
 } catch (Exception e) {
            } catch (Exception e) {50
 // TODO: handle exception
                // TODO: handle exception51
 throw new RuntimeException();
                throw new RuntimeException();52
 }
            }53
 
            54
 }
        }55
 return this.queue.removeFirst();
        return this.queue.removeFirst();56
 }
    }57

58
 
    59
 }
}60

 /**
/** *
 *  */
 */ package patterns.guardedSuspension;
package patterns.guardedSuspension;
 /**
/** * @author Jackie Xie 其实就是缓冲区守护进程的变种,主要功能是:
 * @author Jackie Xie 其实就是缓冲区守护进程的变种,主要功能是: *         维护一个缓冲区,当缓冲区有内容时,通知客户方可以取走,无内容时,缓冲区等待
 *         维护一个缓冲区,当缓冲区有内容时,通知客户方可以取走,无内容时,缓冲区等待 */
 */ public class GuardedSuspension {
public class GuardedSuspension {
 /**
    /** * @param args
     * @param args */
     */ public static void main(String[] args) throws Exception {
    public static void main(String[] args) throws Exception { // TODO Auto-generated method stub
        // TODO Auto-generated method stub RequestQueue rq = new RequestQueue(args[0]);
        RequestQueue rq = new RequestQueue(args[0]); java.rmi.Naming.bind("talker", rq);
        java.rmi.Naming.bind("talker", rq); }
    } }
}
 /**
/** *
 *  */
 */ package patterns.guardedSuspension;
package patterns.guardedSuspension;
 import java.io.BufferedReader;
import java.io.BufferedReader; import java.io.InputStreamReader;
import java.io.InputStreamReader;

 /**
/** * @author Jackie Xie
 * @author Jackie Xie *
 * */
 */ public class TalkClient {
public class TalkClient {
 /**
    /** * @param args
     * @param args */
     */ public static void main(String[] args)throws Exception {
    public static void main(String[] args)throws Exception { // TODO Auto-generated method stub
        // TODO Auto-generated method stub //        rq.start();
//        rq.start(); BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String command ="";
        String command =""; IRequestQueue rq = (IRequestQueue)java.rmi.Naming.lookup("rmi://"+args[0]+"/"+args[1]);
        IRequestQueue rq = (IRequestQueue)java.rmi.Naming.lookup("rmi://"+args[0]+"/"+args[1]); while (!(command=br.readLine().toUpperCase()).equals("END")) {
        while (!(command=br.readLine().toUpperCase()).equals("END")) { if (args[2].equals("say")) {
            if (args[2].equals("say")) { rq.putMessage(command);
                rq.putMessage(command); }
            } if (args[2].equals("listen")) {
            if (args[2].equals("listen")) { System.out.println(rq.getMessage());
                System.out.println(rq.getMessage()); }
            } }
        } }
    }
 }
}
服务器实现类RequesQueue要使用rmic进行编译,编译完毕后,先运行rmiregistry,再使用java 运行reqeustQueue的运行类,最后运行客户端程序
第一次写心得笔记,不当处请砸砖
 
                    
                

 
     
                
            
         
 浙公网安备 33010602011771号
浙公网安备 33010602011771号