Clean Code that Works.

모두 읽어도 좋지만 일고 있을 때에는 쓰면 안돼요.

별명 : Reader Writer, Reader/Writer Lock, Readers/Writer Lock

문맥 : 복수의 쓰레드가 인스턴스를 공유하고 있어 인스턴스의 상태를 참조하는 것뿐인 쓰레드(Reader)와 변경하는 쓰레드(Writer)가 존재하고 있다고 합시다.

문제 : 쓰레드 간에 배타 제어를 하지 않으면 안정성을 잃게 됩니다. 그러나 Single Threaded Execution 패턴을 사용하면 스루풋이 떨어져 버립니다.

해결법 : 우선 『Reader를 제어하는 락』과 『Writer를 제어하는 락』을 나누어 이 두종류의락을 제공하는 ReadWriteLock을 도입해 봅시다. ReadWriteLock은『Writer 끼리 』및 『Reader와 Writer』의 배타 제어를 합니다. 『Reader 끼리』는 충돌해도 안정성에 영향을 주지 않기 때문에 배타 제어는 하지 않습니다. 이것으로 안정성을 잃어 버리지 않고 스루픗을 향상 시킬 수 있습니다. 이것이 Read-Write Lock 패턴이니다.

구현 : 자바에서는 finally를 사용하면 락의 해제를 잊어버리는 것을 방지할 수 있습니다.

관련 : Read-Write Lock 패턴의 ReadWriteLock이 배타 제어를 실현하는 부분에서는 Guarded Suspension 패턴을 사용합니다.
Writer가 전혀 존재하지 않을 때에는 Immutable 패턴을 사용합니다.


- Java언어로 배우는 디자인 패턴 입문 -

내가 만들고 당신이 쓰는

문맥 : 어떤 쓰레드(Producer)에서 다른 쓰레드(Consumer)에 데이터를 넘겨준다고 합시다.

문제 : Producer 와 Consumer의 처리 속도가 다르면 늦은 쪽이 빠른쪽의 다리를 잡아끌어서 스루풋이 떨어진다. 또 Producer가 데이터를 쓸 때 동시에 Consumer가 데이터를 읽으려고 하면 안정성이 떨어진다.

해결법
 
 Producer와 Consumer의 사이에 중간 지점이 되는 Channel을 준비합시다. 그리고 Channel에 복수의 데이터를 보유시킵니다. 그렇게 하면 Producer와 Consumer의 처리 속도 차를 완화할 수 있습니다. 또 Channel중에서 쓰레드의 배타 제어를 하면 데이터의 안정성도 잃어버리지 않습니다. 이것으로 스루풋을 떨어뜨리지 않고 더군다나 복수 쓰레드 간에 안전하게 데이터를 주고받을 수 있습니다.
이것이 Producer-Consumer 패턴입니다.

관련
  Channel이 데이터를 안전하게 주고받는 부분에서는 Guarded Suspension 패턴을 사용합니다.
  Future 패턴에서 반환값을 건넬 때에는 Producer-Consumer 패턴을 사용합니다.
  Worker Thread 패턴으로 요구를 건넬 때에는 Producer-Consumer 패턴을 사용합니다.

ps. 쓰레드간에 직접 주고받는 통신을 하지 않고, 중간에 연결 고리를 두어서 그곳을 통해 거래를 하는 방식..

- Java언어로 배우는 디자인 패턴 입문 -

필요 없으면 관둬요.

문맥 : 복수의 쓰레드가 인스턴스를 공유하고 있다고 할때.

문제 : 복수의 쓰레드가 마음대로 인스턴스에 액세스하면 인스턴스의 안정성을 잃어버리게 된다.
         그러나 안전한 타이밍을 기다리고 있으면 응답성이 저하된다.

해결법 
  인스턴스의 상태가 부적절한 때에는 처리를 중단합시다. 우선 인스턴스의 '적절한 상태'를 '가드 조건' 으로 표현한다. 그리고 안정성을 잃어버릴 위험이 있는 처리를 하기 전에 가드 조건이 충족되었는지 테스트 한다. 가드 조건이 충족되어 있을때에만 실행을 계속 한다.가드 조건이 충족되어 있지 않으면 실핼을 중단(balk)하고 곧장 돌아간다.

구현
  자바에서는 가드 조건의 테스트에 if 문을 사용한다. balk하는 데에는 return으로 메소드에서 돌아오거나 throw로 예외를 던진다. 가드 조건의 테스트와 변경은 Single Threaded Execution 패턴을 사용한다.

관련
  가드 조건이 충족되기까지 기다리고 싶을 때에는 Guarded Suspension을 사용합니다.
  Balking 패턴의 가드 조건의 테스트와 변경을 기술하는 부분에서는 Single Threaded Execution 패턴을 사용합니다.

- Java언어로 배우는 디자인 패턴 입문 -





import java.util.Scanner;

public class CheckPrimeNumber {
 private int input;
 private Scanner scan = new Scanner(System.in);
 private boolean prime;
 
 public CheckPrimeNumber() {
  putInfo();
 }
 
 public void setInputNumber(int input) {
  this.input = input;
 }
 
 public void putInfo() {
  System.out.println("소수 계산 프로그램 입니다.");
 
  System.out.print("계산 하고자 하는 수를 입력 하세요 : ");
  setInputNumber(scan.nextInt());
 
  System.out.println("계산중...");
 
  putNumber(input);
 }
 
 public boolean calculation(int num) {
  prime = true;
     int limit = (int) Math.sqrt ( num ); 

     for ( int i = 2; i <= limit; i++ )
     {
      if ( num % i == 0 )
      {
       prime = false;
       break;
      }
     }
     return prime;
 }
 
 public void putNumber(int num) {
  int j = 0;
  for (int i = 2; i <= num; i++){
   if (calculation(i)) {
    System.out.println(i);
    j++;
   }
  }
  System.out.println("입력한 숫자 "+input+"의 소수의 갯수는 "+j+"개입니다.");
 }
 
 public static void main(String[] args) {
  new CheckPrimeNumber();
 }
}