「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 5)
Guarded Suspension 패턴
Guarded Suspension 패턴에는 guarded wait, spin lock등의 호칭이 있다.
Request.javapublic class Request {
private final String name;
public Request(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return "[ Request " + name + " ]";
}
}
RequestQueue.javaimport java.util.Queue;
import java.util.LinkedList;
public class RequestQueue {
private final Queue<Request> queue = new LinkedList<Request>();
public synchronized Request getRequest() {
while (queue.peek() == null) {
try {
wait(); // キューが空の時は待つ(ウェイトセットに入る)
} catch (InterruptedException e) {
}
}
return queue.remove();
}
public synchronized void putRequest(Request request) {
queue.offer(request);
notifyAll(); // 待っているスレッドに、キューにrequestが入ったことを知らせる
}
}
ClientThread.javaimport java.lang.Math;
public class ClientThread extends Thread {
private final RequestQueue requestQueue;
public ClientThread(RequestQueue requestQueue, String name) {
super(name);
this.requestQueue = requestQueue;
}
public void run() {
for (int i = 0; i <= 100; i++) {
Request request = new Request("No." + i);
System.out.println(Thread.currentThread().getName() + " put " + request);
requestQueue.putRequest(request);
try {
Thread.sleep((int)(Math.random()*10));
} catch (InterruptedException e) {
}
}
}
}
ServerThread.javaimport java.lang.Math;
public class ServerThread extends Thread {
private final RequestQueue requestQueue;
public ServerThread(RequestQueue requestQueue, String name) {
super(name);
this.requestQueue = requestQueue;
}
public void run() {
for (int i = 0; i <= 100; i++) {
Request request = requestQueue.getRequest();
System.out.println(Thread.currentThread().getName() + " get " + request);
try {
Thread.sleep((int)(Math.random()*10));
} catch (InterruptedException e) {
}
}
}
}
Main.javapublic class Main {
public static void main(String[] args) {
RequestQueue requestQueue = new RequestQueue();
new ClientThread(requestQueue, "A").start();
new ServerThread(requestQueue, "B").start();
}
}
실행 결과...
A put [ Request No.95 ]
B get [ Request No.91 ]
B get [ Request No.92 ]
A put [ Request No.96 ]
A put [ Request No.97 ]
B get [ Request No.93 ]
A put [ Request No.98 ]
B get [ Request No.94 ]
A put [ Request No.99 ]
B get [ Request No.95 ]
B get [ Request No.96 ]
B get [ Request No.97 ]
B get [ Request No.98 ]
B get [ Request No.99 ]
...
ClientThread는 SeverThread에 Request 인스턴스를 전달합니다. 이것은 매우 간단한 스레드 간 통신. ClientThread나 ServerThread를 액티브 오브젝트, RequestQueue를 수동 오브젝트라고 부른다.
ClientThread가 Queue에 요청을 던지고(put), ServerThread가 Queue에서 요청을 꺼낸다(get). put과 get은 synchronized로 배타된다.
getReques 메소드는 가장 오래된 요청을 하나 꺼낸다. 요청이 하나도 없는 경우는, 다른 thread가 putRequest할 때까지 기다린다. queue.peek() != null 이라는 조건 즉 Queue 가 비어 있지 않다는 조건이 채워져 있을 필요가 있다. 이러한 충족되어야하는 조건을 Guarded Suspension 패턴의 가드 조건이라고합니다.
putRequest 메소드는 하나의 요청을 추가한다. 그런 다음 notifyAll에서 기다리는 스레드에 알립니다.
wait와 notify에 대해서는
「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 1)
참조.
실행 결과와 같이 B(get)가 A(put)를 추월하지 않는다.
등장인물
GuardedObject 역할은 가드된 메소드(guardedMethod)를 가지고 있는 클래스. 가드 조건이 충족되면 즉시 실행되고, 충족되지 않으면 기다립니다. GuardedObjec 역할은 인스턴스의 상태를 변경하는 메서드(stateChangingMethod)를 가질 수 있다. 샘플 프로그램에서는 RequestQueue 클래스가 이 역할을 맡고, getRequest가 guardedMethod, putRequest가 stateChangingMethod에 대응한다.
관련
「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 1)
「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 2)
「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 3)
「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 4)
Reference
이 문제에 관하여(「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 5)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yoshi-yoshi/items/427be45a8b0044083911
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public class Request {
private final String name;
public Request(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return "[ Request " + name + " ]";
}
}
import java.util.Queue;
import java.util.LinkedList;
public class RequestQueue {
private final Queue<Request> queue = new LinkedList<Request>();
public synchronized Request getRequest() {
while (queue.peek() == null) {
try {
wait(); // キューが空の時は待つ(ウェイトセットに入る)
} catch (InterruptedException e) {
}
}
return queue.remove();
}
public synchronized void putRequest(Request request) {
queue.offer(request);
notifyAll(); // 待っているスレッドに、キューにrequestが入ったことを知らせる
}
}
import java.lang.Math;
public class ClientThread extends Thread {
private final RequestQueue requestQueue;
public ClientThread(RequestQueue requestQueue, String name) {
super(name);
this.requestQueue = requestQueue;
}
public void run() {
for (int i = 0; i <= 100; i++) {
Request request = new Request("No." + i);
System.out.println(Thread.currentThread().getName() + " put " + request);
requestQueue.putRequest(request);
try {
Thread.sleep((int)(Math.random()*10));
} catch (InterruptedException e) {
}
}
}
}
import java.lang.Math;
public class ServerThread extends Thread {
private final RequestQueue requestQueue;
public ServerThread(RequestQueue requestQueue, String name) {
super(name);
this.requestQueue = requestQueue;
}
public void run() {
for (int i = 0; i <= 100; i++) {
Request request = requestQueue.getRequest();
System.out.println(Thread.currentThread().getName() + " get " + request);
try {
Thread.sleep((int)(Math.random()*10));
} catch (InterruptedException e) {
}
}
}
}
public class Main {
public static void main(String[] args) {
RequestQueue requestQueue = new RequestQueue();
new ClientThread(requestQueue, "A").start();
new ServerThread(requestQueue, "B").start();
}
}
...
A put [ Request No.95 ]
B get [ Request No.91 ]
B get [ Request No.92 ]
A put [ Request No.96 ]
A put [ Request No.97 ]
B get [ Request No.93 ]
A put [ Request No.98 ]
B get [ Request No.94 ]
A put [ Request No.99 ]
B get [ Request No.95 ]
B get [ Request No.96 ]
B get [ Request No.97 ]
B get [ Request No.98 ]
B get [ Request No.99 ]
...
Reference
이 문제에 관하여(「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 5)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yoshi-yoshi/items/427be45a8b0044083911텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)