Guarded Suspension 디자인 모델

1. 해결 해 야 할 문제
    Guarded Suspension (보호 일시 정지) 의 핵심 사상 은 서버 프로 세 스 가 준 비 된 후에 만 서 비 스 를 제공 하 는 것 이다.한 장면 을 가정 하면 서버 는 짧 은 시간 안에 대량의 클 라 이언 트 요청 을 받 을 수 있 고 서버 의 부하 가 초과 되 었 을 수도 있 으 며 서버 는 어떠한 사용자 의 요청 도 마음대로 버 릴 수 없다.이때 가장 좋 은 처리 방안 은 클 라 이언 트 가 줄 을 서 라 고 요청 하고 서버 에서 하나씩 처리 하 는 것 이다.이렇게 하면 모든 클 라 이언 트 요청 이 분실 되 지 않도록 보장 할 뿐만 아니 라 서버 가 너무 많은 요청 을 동시에 처리 해서 무 너 지 는 것 도 피 할 수 있다.
2. 관련 된 역할
(1) ServerThread: 서버 스 레 드.요청 대기 열 에서 요청 가 져 오기
(2) Client Thread: 클 라 이언 트 스 레 드.요청 을 제출 하고 공 유 된 요청 대기 열 에 요청 을 삽입 합 니 다.
(3) Request: 클 라 이언 트 요청 을 표시 합 니 다.
(4) RequestQueue: 대기 열 요청.클 라 이언 트 와 서버 가 공동으로 유지 합 니 다.스 레 드 가 안전 해 야 합 니 다.
3 Guarded Suspension 의 구조
    
    프로 세 스 도 를 통 해 알 수 있 듯 이 빈번 한 클 라 이언 트 요청 에서 RequestQueue 는 중간 캐 시 역할 을 하고 처리 되 지 않 은 요청 을 대량으로 저장 하여 클 라 이언 트 의 요청 을 잃 어 버 리 지 않도록 하 는 동시에 서버 가 대량의 병행 요청 을 받 지 않도록 보호 합 니 다.
4 코드 구현
4.1 클 라 이언 트 스 레 드 에 반환 값 없 음
(1)Request.java:
public class Request {
	private String name;
	public Request(String name) {
		// TODO Auto-generated constructor stub
		this.name=name;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Request:"+name;
	}
}
(2)ServerThread.java:
public class ServerThread extends Thread{
	private BlockingQueue<Request> queue;
	public ServerThread(BlockingQueue<Request> queue,String name) {
		// TODO Auto-generated constructor stub
		super(name);
		this.queue=queue;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			/**
			 *         ,    
			 *         ,              ,    ,
			 *         while(true)   ,        ,             ,
			 *             ,       ,        
			 */
			Request request=queue.take();
			System.out.println("Master"+Thread.currentThread().getName()+"    :"+request);
			/**
			 *       
			 */
			Thread.currentThread().sleep(1000);
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
(3)ClientThread.java:
public class ClientThread extends Thread{
	private BlockingQueue<Request> queue;
	public ClientThread(BlockingQueue<Request> queue,String name) {
		// TODO Auto-generated constructor stub
		super(name);
		this.queue=queue;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		/**
		 *                  
		 */
		for(int i=0;i<1;i++){
			/**
			 *     
			 */
			Request request=new Request(Thread.currentThread().getName());
			/**
			 *     
			 */
			try {
				queue.put(request);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		/**
		 *          ,     Server    
		 */
	}
}

(4)Main.java:
public class Main {
	public static void main(String[] args) {
		BlockingQueue<Request> queue=new LinkedBlockingQueue<Request>();
		/**
		 *          
		 */
		for(int i=0;i<30;i++){
			new ServerThread(queue, String.valueOf(i)).start();
		}
		/**
		 *          
		 */
		for(int i=0;i<10;i++){
			new ClientThread(queue, String.valueOf(i)).start();
		}
	}
}

4.2 클 라 이언 트 스 레 드 에 반환 값 이 있 습 니 다.
(1)Request.java:
public class Request {
	private String name;
	private Data data;
	public Request(String name) {
		// TODO Auto-generated constructor stub
		this.name=name;
	}
	public  synchronized Data getData() {
		return  data;

	}
	public synchronized void setData(Data data) {
	    this.data=data;
	
	}
}
(2)Data.java:
public class Data {
	private boolean isReady;
	private String content;
	public synchronized void setContent() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		content="finished";
		isReady=true;
		notifyAll();
		
	}
	public synchronized String getContent() {
		while (!isReady) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return content;
	}

}
(3)ServerTask.java:
/**
 *      callable            
 * @author    
 *
 */
public class ServerTask implements Callable<String>{
	/**
	 *       ,        
	 */
	private BlockingQueue<Request> queue;
	public ServerTask(BlockingQueue<Request> queue) {
		// TODO Auto-generated constructor stub
		this.queue=queue;
	}
	@Override
	public String call() throws Exception {
		// TODO Auto-generated method stub
		/**
		 *         ,       
		 */
		Request request=queue.take();
		/**
		 *          
		 */
		Thread.sleep(1000);
		request.getData().setContent();
		return null;
	}
}
(4)ClientTask.java:
public class ClientTask implements Callable<Data>{
	private BlockingQueue<Request> queue;
	public ClientTask(BlockingQueue<Request> queue) {
		// TODO Auto-generated constructor stub
		this.queue=queue;
	}

	@Override
	public Data call() throws Exception {
		// TODO Auto-generated method stub
		/**
		 *     ,    
		 */
		Request request=new Request(Thread.currentThread().getName());
		request.setData(new Data());
		System.out.println("    ");
		queue.put(request);
		/**
		 *            
		 *       ,  getContent    ,  ,   
		 */
		Data data=request.getData();
		System.out.println("        :"+data.getContent());
		return null;
	}
}
(5)Main.java:
public class Main {
	public static void main(String[] args) throws Exception{
		/**
		 *         
		 * client        
		 * Server        ,  
		 */
		BlockingQueue<Request> queue=new LinkedBlockingQueue<Request>();
		ExecutorService executor=Executors.newCachedThreadPool();
		for(int i=0;i<5;i++){
			executor.submit(new ClientTask(queue));
		}
		for(int i=0;i<5;i++){
			executor.submit(new ServerTask(queue));
		}
	}
}

5 참고 문헌
1 >. 자바 프로그램의 성능 최적화. 갈 일 명 등.

좋은 웹페이지 즐겨찾기