SlideShare a Scribd company logo
1 of 51
Download to read offline
Multithread
    Design Pattern

           ohyecloudy http://ohyecloudy.com
   아꿈사 http://cafe.naver.com/architect1.cafe

                                  2010.6.12
기초적인 멀티쓰레드 디자인 패턴을 다룬 책

이 책에 나온 내용을 요약 발표
Single Threaded Execution
  이 다리를 건널 수 있는 사람은 오직 한 명
Immutable
Guarded Suspension
Balking
Producer-Consumer
Read-Write Lock
Thread-Per-Message
Worker Thread
Future
C++::Boost
한 번에 한 개의 쓰레드 만이
처리를 실행할 수 있도록 제한
public class Gate {
  private int counter = 0;
  private String name = “Nobody”;
  private String address = “Nowhere”;
  public void pass(String name, String address) {
    this.counter++;
    this.name = name;
    this.address = address;
    check();
  }
  public String toString() {
    return
      “No.” + counter + “: “ + name + “, “ + address;
  }
  private void check() {
    if (name.charAt(0) != address.charAt(0)) {
      System.out.println(“*****BROKEN*****” + toString());
    }
  }
}
public class UserThread extends Thread {
  ...
  public void run() {
    while(thue) {
      gate.pass(myname, myaddress);
    }
  }
}

public class Main {
  public static void main(String[] args) {
    Gate gate = new Gate();

        new UserThread(gate, “Alice”, “Alaska”).start();
        new UserThread(gate, “Bobby”, “Brazil”).start();
        new UserThread(gate, “Chris”, “Canada”).start();
    }
}
쓰레드 세이프thread-safe ?
    쓰레드 여러개가 이용해도 안젂성safety이 유지?
    쓰레드 여러개가 이용해도 객체를
    망가뜨리지 않는가?
public class Gate {
  private int counter = 0;
  private String name = “Nobody”;
  private String address = “Nowhere”;
  public void pass(String name, String address) {
    this.counter++;
    this.name = name;            2. Bobby 쓰레드가 여기까지 짂행
    this.address = address;       1. Alice 쓰레드가 여기까지 짂행
    check();                          3. Alice 쓰레드가 다시 짂행
  }
  public String toString() {
    return
      “No.” + counter + “: “ + name + “, “ + address;
  }
  private void check() {
    if (name.charAt(0) != address.charAt(0)) {
      System.out.println(“*****BROKEN*****” + toString());
    }
                           4. name = “Bobby”, address=“Alaska”
  }
}
쓰레드 세이프하게 맊들자.

동시에 한 개의 쓰레드에서만 실행되는 걸 보장
객체가 깨지는 것을 막는다.
  synchronized keyword
public class Gate {
  private int counter = 0;
  private String name = “Nobody”;
  private String address = “Nowhere”;
  public synchronized void pass(
    String name, String address) {
    this.counter++;
    this.name = name;
    this.address = address;
    check();
  }
  public synchronized String toString() {
    return
      “No.” + counter + “: “ + name + “, “ + address;
  }
  private void check() {
    if (name.charAt(0) != address.charAt(0)) {
      System.out.println(“*****BROKEN*****” + toString());
    }
  }
}
언제 사용하는가?
멀티 쓰레드
   당연. 싱글 쓰레드는 필요 없다.

쓰레드 여러개가 접근access할 때

상태가 변화할 가능성이 있을 때

안정성을 확보할 필요가 있을 때
Single Threaded Execution
Immutable
  망가뜨리고 싶어도 망가지지 않는다.
Guarded Suspension
Balking
Producer-Consumer
Read-Write Lock
Thread-Per-Message
Worker Thread
Future
C++::Boost
Immutable
    불변의, 변하는 것이 없는


인스턴스 상태가 젃대 변하지 않는 클래스는
상호 배제mutual exclusion가 필요 없다.
public final class Person {

    private final String name;
    private final String address;

    public Person(String name, String address) {
      this.name = name;
      this.address = address;
    }
    public String getName() {
      return name;
    }
    public String getAddress() {
      return address;
    }
    public String toString() {
      return name + “ , “ + address;
    }
}
언제 사용하는가?
인스턴스 생성 후 상태가 변하지 않을 때
  setter 메소드가 없다.


자주 접근하는 공유 인스턴스
  상호 배제가 필요 없다는게 장점
      빠르다는 이야기
조낸 접근 맋이 해서
Immutable 패턴을 사용하고 싶은데,

Setter가 있네요. 망했네요.

이런 경우는 죽어도
Immutable 패턴을 못 쓰나요?
Mutable 과 Immutable로
쪼갤 수 있는지 검토

String, StringBuffer가 좋은 예
Single Threaded Execution
Immutable
Guarded Suspension
  준비가 될 때까지 기다려 주세요.
Balking
Producer-Consumer
Read-Write Lock
Thread-Per-Message
Worker Thread
Future
C++::Boost
Guarded
    보호받고 있다.


Suspension
    일시 정지함


처리해도 될 때까지 기다린다.
    guarded wait, spin lock, busy wait
// immutable
public class Request {
  private final String name;
  ...
  public String getName() {...}
  public String toString() {...}
}


public class RequestQueue {
  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();
    }
}
public class ClientThread extends Thread {
  ...
  public void run() {
    while (true) {
      ...
      requestQueue.putRequest(request);
    }
  }
}

public class ServerThread extends Thread {
  ...
  public void run() {
    while (true) {
      Request request = requestQueue.getRequest();
      ...
    }
  }
}
Single Threaded Execution
Immutable
Guarded Suspension
Balking
  필요 없으면 관둬요
Producer-Consumer
Read-Write Lock
Thread-Per-Message
Worker Thread
Future
C++::Boost
balk
       중단하고 돌아가다
       야구빠 : 생각하시는 그 보크 맞습니다.


가드 조건
       Guarded Suspension 패턴에 등장
       단, 기다리지 않고 바로 중단한다.
public class Data {
  ...

    public synchronized void change(String newContent) {
      content = newContent;
      changed = true;
    }

    public synchronized void save() {
      if (!changed) {
        return;
      }
      ...
    }
}
언제 사용하는가?
굳이 처리할 필요가 없는 경우

가드 조건이 충족되기를
기다리고 싶지 않은 경우

가드 조건을 맊족하는 것이 처음 1회뿐인 경우
  예) 초기화
Single Threaded Execution
Immutable
Guarded Suspension
Balking
Producer-Consumer
  내가 만들고 당신이 사용한다.
Read-Write Lock
Thread-Per-Message
Worker Thread
Future
C++::Boost
producer
    생산자 : 데이터를 작성하는 쓰레드


consumer
    소비자 : 데이터를 이용하는 쓰레드


channel
    생산자와 소비자를 이어주는 중개 역할.
    생산자와 소비자 처리 속도 차이를 메운다.
    상호 배제는 여기에서만 수행
public class MakerThread extends Thread {
  ...
  public void run() {
    while (true) {
      Thread.sleep(GetRandom());
      table.put(cake);
    }
  }
}

public class EaterThread extends Thread {
  ...
  public void run() {
    while (true) {
      String cake = table.take();
      Thread.sleep(GetRandom());
    }
  }
}
public class Table {
  ...

    public synchronized void put(String cake) {
      while (count >= buffer.length) {
        wait();
      }
      // 케이크를 놓는다.
      notifyAll();
    }

    public synchronized String take() {
      while (count <= 0) {
        wait();
      }
      // 죿 케이크를 죾비
      notifyAll();
      return cake;
    }

}
Single Threaded Execution
Immutable
Guarded Suspension
Balking
Producer-Consumer
Read-Write Lock
  다 같이 읽는 것은 상관없지만 읽는 중간에 쓰면 안돼요.
Thread-Per-Message
Worker Thread
Future
C++::Boost
읽기 : 읽기 쓰레드 여러개 접근 문제 없다.
쓰기 : 인스턴스 상태가 바뀜
   다른 쓰레드가 읽던가 쓰던가 다 문제 생김.


상호 배제를 나눠서 하자.
   읽기 상호 배제
   쓰기 상호 배제
public class Data {
  ...
  public char[] read() {
    lock.readLock();
    try {
      return doRead();
    } finally {
      lock.readUnlock();
    }
  }

    public void write(char c) {
      lock.writeLock();
      try {
        doWrite(c);
      } finally {
        lock.writeUnlock();
      }
    }

}
public final class ReadWriteLock {
  private int readingReaders = 0;
  private int waitingWriters = 0;
  // 한번에 한 쓰레드맊 쓰기가 가능하기 때문에 대기자를 기록.
  private int writingWriters = 0;
  // 읽기, 쓰기 한쪽이 굶어 죽는 것을 방지.
  private boolean preferWriter = true;

 public synchronized void readLock() {
   // 쓰기 락이 걸렸거나 기다리는 쓰기 락을 걸어줘야 할 때.
   while (writingWriters > 0 ||
           (preferWriter && waitingWriters > 0)) {
     wait();
   }
   readingReaders++;
 }

 public synchronized void readUnlock() {
   readingReaders--;
   preferWriter = true;
   notifyAll();
 }
public synchronized void writerLock() {
   waitingWriters++;
   try {
     while (readingReaders > 0 || writingWriters > 0) {
       wait();
     }
   } finally {
     waitingWriters--;
   }
   writingWriters++;
 }

    public synchronized void writerUnlock() {
      writingWriters--;
      preferWriter = false;
      notifyAll();
    }
}
언제 사용하는가?
읽기 빈도가 쓰기 빈도보다 높을 때

읽기 처리가 무거울 때
Single Threaded Execution
Immutable
Guarded Suspension
Balking
Producer-Consumer
Read-Write Lock
Thread-Per-Message
  이 일을 부탁해요
Worker Thread
Future
C++::Boost
명령이나 요구마다
  새로 만든 쓰레드 한 개가 할당
  그 쓰레드가 처리


실행 순서 보장하지 않는다.

실행 결과를 받아보지 못한다.
public class Host {
  public void request(
    final int count, final char c) {
    new Thread() {
      public void run() {
        helper.handle(count, c);
      }
    }.start();
  }
}

public class Main {
  public static void Main(String[] args) {
    Host host = new Host();
    host.request(10, ‘A’);
    host.request(20, ‘B’);
    host.request(30, ‘C’);
  }
}
Single Threaded Execution
Immutable
Guarded Suspension
Balking
Producer-Consumer
Read-Write Lock
Thread-Per-Message
Worker Thread
  일이 올 때까지 기다리고, 일이 오면 작업한다.
Future
C++::Boost
일을 처리할 수 있는 쓰레드를 미리 맊듬
   Worker Thread

신나게 굴린다.
   일이 없을 때맊 쉬고 일이 주어지면
   놀고 있는 쓰레드가 처리.

Thread-Per-Message 패턴에서
새로운 thread를 매번 생성하는 부담을
덜어주는 패턴

Thread Pool이라고도 불림
// 리퀘스트를 받아서 전달. 워커 쓰레드를 보유.
public class Channel {
  ...
  public void startWorkers() {
    for (int i = 0; i < threadPool.length; ++i) {
      threadPool[i].start();
    }
  }
  public synchronized void putRequest(Request request) {
    while (count >= requestQueue.length) {
      wait();
    }
    // 리퀘스트를 저장
    notifyAll();
  }
  public synchronized Request takeRequest() {
    while (count <= 0) {
      wait();
    }
    // 큐에서 리퀘스트를 가져옴.
    notifyAll();
    return request;
  }
}
public class WorkerThread extends Thread {
  private final Channel channel;
  ...
  public void run() {
    while (true) {
      Request request = channel.takeRequest();
      request.execute();
    }
  }
}
Single Threaded Execution
Immutable
Guarded Suspension
Balking
Producer-Consumer
Read-Write Lock
Thread-Per-Message
Worker Thread
Future
  먼저 교환권을 받으세요
C++::Boost
Future
    미래
    경제 용어) 선물


실행 결과를 구할 때까지 기다리는 대신에
바로 교홖권을 받는다.
    교환권으로 실행 결과를 받음.
    아직 결과가 안 나왔다면 기다린다.


Thread-Per-Message, Worker Thread에서
실행 결과가 필요할 때 사용.
public class Host {
  public Data request(final int count, final char c) {
    final FutureData future = new FutureData();

        new Thread() {
          public void run() {
            RealData realData = new RealData(count, c);
            future.setRealData(realData);
          }
        }.start();

        return future;
    }
}
public class FutureData {
  ...

    public synchronized void setRealData(
      RealData realdata) {
      if (ready) {
        return; // balk
      }
      this.realdata = realdata;
      this.ready = true;
      notifyAll();
    }

    public synchronized String getContent() {
      while (!ready) {
        wait();
      }
      return realdata.getContent();
    }

}
public class ReadData {
  ...
  public RealData(int count, char c) {
    // 실제 결과물을 계산한다.
    // 시간이 걸리는 작업
    this.content = new String(buffer);
  }

    public String getContent() {
      return content();
    }
}
Single Threaded Execution
Immutable
Guarded Suspension
Balking
Producer-Consumer
Read-Write Lock
Thread-Per-Message
Worker Thread
Future
C++::Boost
Java 좋다.
다 구현돼 있네.

C++에서 패턴에맊 집중해서
편하게 써보고 싶다면

Boost를 사용하면 된다.
class ReadWriteLock
{
public:
  void ReadLock()
  {
    boost::mutex::scoped_lock lock(m_mutex);
    {
      while (m_writingWriters > 0 || (m_preferWriter && m_waitingWriters > 0))
      {
        m_cond.wait(lock);
      }
      m_readingReaders++;
    }
  }
  void ReadUnlock()
  {
    boost::mutex::scoped_lock lock(m_mutex);
    {
      m_readingReaders--;
      m_preferWriter = true;
      m_cond.notify_all();
    }
  }
  ...

private:
  boost::mutex                m_mutex;
  boost::condition_variable   m_cond;
};
Multithread design pattern

More Related Content

What's hot

multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것
multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것
multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것흥배 최
 
[오픈소스컨설팅]Day #1 MySQL 엔진소개, 튜닝, 백업 및 복구, 업그레이드방법
[오픈소스컨설팅]Day #1 MySQL 엔진소개, 튜닝, 백업 및 복구, 업그레이드방법[오픈소스컨설팅]Day #1 MySQL 엔진소개, 튜닝, 백업 및 복구, 업그레이드방법
[오픈소스컨설팅]Day #1 MySQL 엔진소개, 튜닝, 백업 및 복구, 업그레이드방법Ji-Woong Choi
 
Redis cluster
Redis clusterRedis cluster
Redis clusteriammutex
 
[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축
[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축
[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축Juhong Park
 
[수정본] 우아한 객체지향
[수정본] 우아한 객체지향[수정본] 우아한 객체지향
[수정본] 우아한 객체지향Young-Ho Cho
 
webservice scaling for newbie
webservice scaling for newbiewebservice scaling for newbie
webservice scaling for newbieDaeMyung Kang
 
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 Seoul
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 SeoulElastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 Seoul
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 SeoulSeungYong Oh
 
아마존 클라우드와 함께한 1개월, 쿠키런 사례중심 (KGC 2013)
아마존 클라우드와 함께한 1개월, 쿠키런 사례중심 (KGC 2013)아마존 클라우드와 함께한 1개월, 쿠키런 사례중심 (KGC 2013)
아마존 클라우드와 함께한 1개월, 쿠키런 사례중심 (KGC 2013)Brian Hong
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010devCAT Studio, NEXON
 
mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교Woo Yeong Choi
 
임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013devCAT Studio, NEXON
 
이벤트 기반 분산 시스템을 향한 여정
이벤트 기반 분산 시스템을 향한 여정이벤트 기반 분산 시스템을 향한 여정
이벤트 기반 분산 시스템을 향한 여정Arawn Park
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS MeetupLINAGORA
 
Managing Your Security Logs with Elasticsearch
Managing Your Security Logs with ElasticsearchManaging Your Security Logs with Elasticsearch
Managing Your Security Logs with ElasticsearchVic Hargrave
 
Troubleshooting redis
Troubleshooting redisTroubleshooting redis
Troubleshooting redisDaeMyung Kang
 
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"용근 권
 
MongoDB Fundamentals
MongoDB FundamentalsMongoDB Fundamentals
MongoDB FundamentalsMongoDB
 
게임 분산 서버 구조
게임 분산 서버 구조게임 분산 서버 구조
게임 분산 서버 구조Hyunjik Bae
 
Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Kwen Won Lee
 

What's hot (20)

multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것
multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것
multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것
 
[오픈소스컨설팅]Day #1 MySQL 엔진소개, 튜닝, 백업 및 복구, 업그레이드방법
[오픈소스컨설팅]Day #1 MySQL 엔진소개, 튜닝, 백업 및 복구, 업그레이드방법[오픈소스컨설팅]Day #1 MySQL 엔진소개, 튜닝, 백업 및 복구, 업그레이드방법
[오픈소스컨설팅]Day #1 MySQL 엔진소개, 튜닝, 백업 및 복구, 업그레이드방법
 
Redis cluster
Redis clusterRedis cluster
Redis cluster
 
[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축
[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축
[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축
 
[수정본] 우아한 객체지향
[수정본] 우아한 객체지향[수정본] 우아한 객체지향
[수정본] 우아한 객체지향
 
webservice scaling for newbie
webservice scaling for newbiewebservice scaling for newbie
webservice scaling for newbie
 
Mongo db 최범균
Mongo db 최범균Mongo db 최범균
Mongo db 최범균
 
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 Seoul
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 SeoulElastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 Seoul
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 Seoul
 
아마존 클라우드와 함께한 1개월, 쿠키런 사례중심 (KGC 2013)
아마존 클라우드와 함께한 1개월, 쿠키런 사례중심 (KGC 2013)아마존 클라우드와 함께한 1개월, 쿠키런 사례중심 (KGC 2013)
아마존 클라우드와 함께한 1개월, 쿠키런 사례중심 (KGC 2013)
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010
 
mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교
 
임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013
 
이벤트 기반 분산 시스템을 향한 여정
이벤트 기반 분산 시스템을 향한 여정이벤트 기반 분산 시스템을 향한 여정
이벤트 기반 분산 시스템을 향한 여정
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS Meetup
 
Managing Your Security Logs with Elasticsearch
Managing Your Security Logs with ElasticsearchManaging Your Security Logs with Elasticsearch
Managing Your Security Logs with Elasticsearch
 
Troubleshooting redis
Troubleshooting redisTroubleshooting redis
Troubleshooting redis
 
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
 
MongoDB Fundamentals
MongoDB FundamentalsMongoDB Fundamentals
MongoDB Fundamentals
 
게임 분산 서버 구조
게임 분산 서버 구조게임 분산 서버 구조
게임 분산 서버 구조
 
Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표
 

Similar to Multithread design pattern

Multi-thread : producer - consumer
Multi-thread : producer - consumerMulti-thread : producer - consumer
Multi-thread : producer - consumerChang Yoon Oh
 
Design Pattern - Multithread Ch10
Design Pattern - Multithread Ch10Design Pattern - Multithread Ch10
Design Pattern - Multithread Ch10hyun soomyung
 
android_thread
android_threadandroid_thread
android_threadhandfoot
 
.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기Seong Won Mun
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GDG Korea
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화sung ki choi
 
Realm은 어떻게 효율적인 데이터베이스를 만들었나?
Realm은 어떻게 효율적인 데이터베이스를 만들었나?Realm은 어떻게 효율적인 데이터베이스를 만들었나?
Realm은 어떻게 효율적인 데이터베이스를 만들었나?Leonardo YongUk Kim
 
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기흥배 최
 
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2도현 김
 
읽기 좋은 코드가 좋은 코드다 Part one
읽기 좋은 코드가 좋은 코드다   Part one읽기 좋은 코드가 좋은 코드다   Part one
읽기 좋은 코드가 좋은 코드다 Part oneJi Hun Kim
 
Effective unit testing ch3. 테스트더블
Effective unit testing   ch3. 테스트더블Effective unit testing   ch3. 테스트더블
Effective unit testing ch3. 테스트더블YongEun Choi
 
Let's Go (golang)
Let's Go (golang)Let's Go (golang)
Let's Go (golang)상욱 송
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기jongho jeong
 
Design patterns
Design patternsDesign patterns
Design patternsdf
 
[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍NAVER D2
 
실용주의 디자인패턴 2 인터페이스로 프로그래밍하기
실용주의 디자인패턴   2 인터페이스로 프로그래밍하기실용주의 디자인패턴   2 인터페이스로 프로그래밍하기
실용주의 디자인패턴 2 인터페이스로 프로그래밍하기Cosmos Shin
 

Similar to Multithread design pattern (20)

Multi-thread : producer - consumer
Multi-thread : producer - consumerMulti-thread : producer - consumer
Multi-thread : producer - consumer
 
Design Pattern - Multithread Ch10
Design Pattern - Multithread Ch10Design Pattern - Multithread Ch10
Design Pattern - Multithread Ch10
 
Clean code appendix 1
Clean code appendix 1Clean code appendix 1
Clean code appendix 1
 
android_thread
android_threadandroid_thread
android_thread
 
Gcd ppt
Gcd pptGcd ppt
Gcd ppt
 
.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
 
Realm은 어떻게 효율적인 데이터베이스를 만들었나?
Realm은 어떻게 효율적인 데이터베이스를 만들었나?Realm은 어떻게 효율적인 데이터베이스를 만들었나?
Realm은 어떻게 효율적인 데이터베이스를 만들었나?
 
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
 
Storm 훑어보기
Storm 훑어보기Storm 훑어보기
Storm 훑어보기
 
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2
 
Spring Boot 2
Spring Boot 2Spring Boot 2
Spring Boot 2
 
읽기 좋은 코드가 좋은 코드다 Part one
읽기 좋은 코드가 좋은 코드다   Part one읽기 좋은 코드가 좋은 코드다   Part one
읽기 좋은 코드가 좋은 코드다 Part one
 
Effective unit testing ch3. 테스트더블
Effective unit testing   ch3. 테스트더블Effective unit testing   ch3. 테스트더블
Effective unit testing ch3. 테스트더블
 
Let's Go (golang)
Let's Go (golang)Let's Go (golang)
Let's Go (golang)
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기
 
Design patterns
Design patternsDesign patterns
Design patterns
 
[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍
 
실용주의 디자인패턴 2 인터페이스로 프로그래밍하기
실용주의 디자인패턴   2 인터페이스로 프로그래밍하기실용주의 디자인패턴   2 인터페이스로 프로그래밍하기
실용주의 디자인패턴 2 인터페이스로 프로그래밍하기
 

More from 종빈 오

트위터 봇 개발 후기
트위터 봇 개발 후기트위터 봇 개발 후기
트위터 봇 개발 후기종빈 오
 
적당한 스터디 발표자료 만들기 2.0
적당한 스터디 발표자료 만들기 2.0적당한 스터디 발표자료 만들기 2.0
적당한 스터디 발표자료 만들기 2.0종빈 오
 
페리 수열(Farey sequence)
페리 수열(Farey sequence)페리 수열(Farey sequence)
페리 수열(Farey sequence)종빈 오
 
내가 본 미드 이야기
내가 본 미드 이야기내가 본 미드 이야기
내가 본 미드 이야기종빈 오
 
비트 경제와 공짜
비트 경제와 공짜비트 경제와 공짜
비트 경제와 공짜종빈 오
 
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해종빈 오
 
[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스종빈 오
 
Intrusive data structure 소개
Intrusive data structure 소개Intrusive data structure 소개
Intrusive data structure 소개종빈 오
 
2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템종빈 오
 
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81종빈 오
 
[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments종빈 오
 
넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우종빈 오
 
[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합종빈 오
 
LevelDB 간단한 소개
LevelDB 간단한 소개LevelDB 간단한 소개
LevelDB 간단한 소개종빈 오
 
[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline종빈 오
 
[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당종빈 오
 
[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary종빈 오
 
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬종빈 오
 
[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명종빈 오
 
[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering종빈 오
 

More from 종빈 오 (20)

트위터 봇 개발 후기
트위터 봇 개발 후기트위터 봇 개발 후기
트위터 봇 개발 후기
 
적당한 스터디 발표자료 만들기 2.0
적당한 스터디 발표자료 만들기 2.0적당한 스터디 발표자료 만들기 2.0
적당한 스터디 발표자료 만들기 2.0
 
페리 수열(Farey sequence)
페리 수열(Farey sequence)페리 수열(Farey sequence)
페리 수열(Farey sequence)
 
내가 본 미드 이야기
내가 본 미드 이야기내가 본 미드 이야기
내가 본 미드 이야기
 
비트 경제와 공짜
비트 경제와 공짜비트 경제와 공짜
비트 경제와 공짜
 
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
 
[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스
 
Intrusive data structure 소개
Intrusive data structure 소개Intrusive data structure 소개
Intrusive data structure 소개
 
2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템
 
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
 
[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments
 
넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우
 
[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합
 
LevelDB 간단한 소개
LevelDB 간단한 소개LevelDB 간단한 소개
LevelDB 간단한 소개
 
[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline
 
[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당
 
[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary
 
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
 
[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명
 
[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering
 

Multithread design pattern

  • 1. Multithread Design Pattern ohyecloudy http://ohyecloudy.com 아꿈사 http://cafe.naver.com/architect1.cafe 2010.6.12
  • 2. 기초적인 멀티쓰레드 디자인 패턴을 다룬 책 이 책에 나온 내용을 요약 발표
  • 3. Single Threaded Execution 이 다리를 건널 수 있는 사람은 오직 한 명 Immutable Guarded Suspension Balking Producer-Consumer Read-Write Lock Thread-Per-Message Worker Thread Future C++::Boost
  • 4. 한 번에 한 개의 쓰레드 만이 처리를 실행할 수 있도록 제한
  • 5. public class Gate { private int counter = 0; private String name = “Nobody”; private String address = “Nowhere”; public void pass(String name, String address) { this.counter++; this.name = name; this.address = address; check(); } public String toString() { return “No.” + counter + “: “ + name + “, “ + address; } private void check() { if (name.charAt(0) != address.charAt(0)) { System.out.println(“*****BROKEN*****” + toString()); } } }
  • 6. public class UserThread extends Thread { ... public void run() { while(thue) { gate.pass(myname, myaddress); } } } public class Main { public static void main(String[] args) { Gate gate = new Gate(); new UserThread(gate, “Alice”, “Alaska”).start(); new UserThread(gate, “Bobby”, “Brazil”).start(); new UserThread(gate, “Chris”, “Canada”).start(); } }
  • 7. 쓰레드 세이프thread-safe ? 쓰레드 여러개가 이용해도 안젂성safety이 유지? 쓰레드 여러개가 이용해도 객체를 망가뜨리지 않는가?
  • 8. public class Gate { private int counter = 0; private String name = “Nobody”; private String address = “Nowhere”; public void pass(String name, String address) { this.counter++; this.name = name; 2. Bobby 쓰레드가 여기까지 짂행 this.address = address; 1. Alice 쓰레드가 여기까지 짂행 check(); 3. Alice 쓰레드가 다시 짂행 } public String toString() { return “No.” + counter + “: “ + name + “, “ + address; } private void check() { if (name.charAt(0) != address.charAt(0)) { System.out.println(“*****BROKEN*****” + toString()); } 4. name = “Bobby”, address=“Alaska” } }
  • 9. 쓰레드 세이프하게 맊들자. 동시에 한 개의 쓰레드에서만 실행되는 걸 보장 객체가 깨지는 것을 막는다. synchronized keyword
  • 10. public class Gate { private int counter = 0; private String name = “Nobody”; private String address = “Nowhere”; public synchronized void pass( String name, String address) { this.counter++; this.name = name; this.address = address; check(); } public synchronized String toString() { return “No.” + counter + “: “ + name + “, “ + address; } private void check() { if (name.charAt(0) != address.charAt(0)) { System.out.println(“*****BROKEN*****” + toString()); } } }
  • 11. 언제 사용하는가? 멀티 쓰레드 당연. 싱글 쓰레드는 필요 없다. 쓰레드 여러개가 접근access할 때 상태가 변화할 가능성이 있을 때 안정성을 확보할 필요가 있을 때
  • 12. Single Threaded Execution Immutable 망가뜨리고 싶어도 망가지지 않는다. Guarded Suspension Balking Producer-Consumer Read-Write Lock Thread-Per-Message Worker Thread Future C++::Boost
  • 13. Immutable 불변의, 변하는 것이 없는 인스턴스 상태가 젃대 변하지 않는 클래스는 상호 배제mutual exclusion가 필요 없다.
  • 14. public final class Person { private final String name; private final String address; public Person(String name, String address) { this.name = name; this.address = address; } public String getName() { return name; } public String getAddress() { return address; } public String toString() { return name + “ , “ + address; } }
  • 15. 언제 사용하는가? 인스턴스 생성 후 상태가 변하지 않을 때 setter 메소드가 없다. 자주 접근하는 공유 인스턴스 상호 배제가 필요 없다는게 장점 빠르다는 이야기
  • 16. 조낸 접근 맋이 해서 Immutable 패턴을 사용하고 싶은데, Setter가 있네요. 망했네요. 이런 경우는 죽어도 Immutable 패턴을 못 쓰나요?
  • 17. Mutable 과 Immutable로 쪼갤 수 있는지 검토 String, StringBuffer가 좋은 예
  • 18. Single Threaded Execution Immutable Guarded Suspension 준비가 될 때까지 기다려 주세요. Balking Producer-Consumer Read-Write Lock Thread-Per-Message Worker Thread Future C++::Boost
  • 19. Guarded 보호받고 있다. Suspension 일시 정지함 처리해도 될 때까지 기다린다. guarded wait, spin lock, busy wait
  • 20. // immutable public class Request { private final String name; ... public String getName() {...} public String toString() {...} } public class RequestQueue { 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(); } }
  • 21. public class ClientThread extends Thread { ... public void run() { while (true) { ... requestQueue.putRequest(request); } } } public class ServerThread extends Thread { ... public void run() { while (true) { Request request = requestQueue.getRequest(); ... } } }
  • 22. Single Threaded Execution Immutable Guarded Suspension Balking 필요 없으면 관둬요 Producer-Consumer Read-Write Lock Thread-Per-Message Worker Thread Future C++::Boost
  • 23. balk 중단하고 돌아가다 야구빠 : 생각하시는 그 보크 맞습니다. 가드 조건 Guarded Suspension 패턴에 등장 단, 기다리지 않고 바로 중단한다.
  • 24. public class Data { ... public synchronized void change(String newContent) { content = newContent; changed = true; } public synchronized void save() { if (!changed) { return; } ... } }
  • 25. 언제 사용하는가? 굳이 처리할 필요가 없는 경우 가드 조건이 충족되기를 기다리고 싶지 않은 경우 가드 조건을 맊족하는 것이 처음 1회뿐인 경우 예) 초기화
  • 26. Single Threaded Execution Immutable Guarded Suspension Balking Producer-Consumer 내가 만들고 당신이 사용한다. Read-Write Lock Thread-Per-Message Worker Thread Future C++::Boost
  • 27. producer 생산자 : 데이터를 작성하는 쓰레드 consumer 소비자 : 데이터를 이용하는 쓰레드 channel 생산자와 소비자를 이어주는 중개 역할. 생산자와 소비자 처리 속도 차이를 메운다. 상호 배제는 여기에서만 수행
  • 28. public class MakerThread extends Thread { ... public void run() { while (true) { Thread.sleep(GetRandom()); table.put(cake); } } } public class EaterThread extends Thread { ... public void run() { while (true) { String cake = table.take(); Thread.sleep(GetRandom()); } } }
  • 29. public class Table { ... public synchronized void put(String cake) { while (count >= buffer.length) { wait(); } // 케이크를 놓는다. notifyAll(); } public synchronized String take() { while (count <= 0) { wait(); } // 죿 케이크를 죾비 notifyAll(); return cake; } }
  • 30. Single Threaded Execution Immutable Guarded Suspension Balking Producer-Consumer Read-Write Lock 다 같이 읽는 것은 상관없지만 읽는 중간에 쓰면 안돼요. Thread-Per-Message Worker Thread Future C++::Boost
  • 31. 읽기 : 읽기 쓰레드 여러개 접근 문제 없다. 쓰기 : 인스턴스 상태가 바뀜 다른 쓰레드가 읽던가 쓰던가 다 문제 생김. 상호 배제를 나눠서 하자. 읽기 상호 배제 쓰기 상호 배제
  • 32. public class Data { ... public char[] read() { lock.readLock(); try { return doRead(); } finally { lock.readUnlock(); } } public void write(char c) { lock.writeLock(); try { doWrite(c); } finally { lock.writeUnlock(); } } }
  • 33. public final class ReadWriteLock { private int readingReaders = 0; private int waitingWriters = 0; // 한번에 한 쓰레드맊 쓰기가 가능하기 때문에 대기자를 기록. private int writingWriters = 0; // 읽기, 쓰기 한쪽이 굶어 죽는 것을 방지. private boolean preferWriter = true; public synchronized void readLock() { // 쓰기 락이 걸렸거나 기다리는 쓰기 락을 걸어줘야 할 때. while (writingWriters > 0 || (preferWriter && waitingWriters > 0)) { wait(); } readingReaders++; } public synchronized void readUnlock() { readingReaders--; preferWriter = true; notifyAll(); }
  • 34. public synchronized void writerLock() { waitingWriters++; try { while (readingReaders > 0 || writingWriters > 0) { wait(); } } finally { waitingWriters--; } writingWriters++; } public synchronized void writerUnlock() { writingWriters--; preferWriter = false; notifyAll(); } }
  • 35. 언제 사용하는가? 읽기 빈도가 쓰기 빈도보다 높을 때 읽기 처리가 무거울 때
  • 36. Single Threaded Execution Immutable Guarded Suspension Balking Producer-Consumer Read-Write Lock Thread-Per-Message 이 일을 부탁해요 Worker Thread Future C++::Boost
  • 37. 명령이나 요구마다 새로 만든 쓰레드 한 개가 할당 그 쓰레드가 처리 실행 순서 보장하지 않는다. 실행 결과를 받아보지 못한다.
  • 38. public class Host { public void request( final int count, final char c) { new Thread() { public void run() { helper.handle(count, c); } }.start(); } } public class Main { public static void Main(String[] args) { Host host = new Host(); host.request(10, ‘A’); host.request(20, ‘B’); host.request(30, ‘C’); } }
  • 39. Single Threaded Execution Immutable Guarded Suspension Balking Producer-Consumer Read-Write Lock Thread-Per-Message Worker Thread 일이 올 때까지 기다리고, 일이 오면 작업한다. Future C++::Boost
  • 40. 일을 처리할 수 있는 쓰레드를 미리 맊듬 Worker Thread 신나게 굴린다. 일이 없을 때맊 쉬고 일이 주어지면 놀고 있는 쓰레드가 처리. Thread-Per-Message 패턴에서 새로운 thread를 매번 생성하는 부담을 덜어주는 패턴 Thread Pool이라고도 불림
  • 41. // 리퀘스트를 받아서 전달. 워커 쓰레드를 보유. public class Channel { ... public void startWorkers() { for (int i = 0; i < threadPool.length; ++i) { threadPool[i].start(); } } public synchronized void putRequest(Request request) { while (count >= requestQueue.length) { wait(); } // 리퀘스트를 저장 notifyAll(); } public synchronized Request takeRequest() { while (count <= 0) { wait(); } // 큐에서 리퀘스트를 가져옴. notifyAll(); return request; } }
  • 42. public class WorkerThread extends Thread { private final Channel channel; ... public void run() { while (true) { Request request = channel.takeRequest(); request.execute(); } } }
  • 43. Single Threaded Execution Immutable Guarded Suspension Balking Producer-Consumer Read-Write Lock Thread-Per-Message Worker Thread Future 먼저 교환권을 받으세요 C++::Boost
  • 44. Future 미래 경제 용어) 선물 실행 결과를 구할 때까지 기다리는 대신에 바로 교홖권을 받는다. 교환권으로 실행 결과를 받음. 아직 결과가 안 나왔다면 기다린다. Thread-Per-Message, Worker Thread에서 실행 결과가 필요할 때 사용.
  • 45. public class Host { public Data request(final int count, final char c) { final FutureData future = new FutureData(); new Thread() { public void run() { RealData realData = new RealData(count, c); future.setRealData(realData); } }.start(); return future; } }
  • 46. public class FutureData { ... public synchronized void setRealData( RealData realdata) { if (ready) { return; // balk } this.realdata = realdata; this.ready = true; notifyAll(); } public synchronized String getContent() { while (!ready) { wait(); } return realdata.getContent(); } }
  • 47. public class ReadData { ... public RealData(int count, char c) { // 실제 결과물을 계산한다. // 시간이 걸리는 작업 this.content = new String(buffer); } public String getContent() { return content(); } }
  • 48. Single Threaded Execution Immutable Guarded Suspension Balking Producer-Consumer Read-Write Lock Thread-Per-Message Worker Thread Future C++::Boost
  • 49. Java 좋다. 다 구현돼 있네. C++에서 패턴에맊 집중해서 편하게 써보고 싶다면 Boost를 사용하면 된다.
  • 50. class ReadWriteLock { public: void ReadLock() { boost::mutex::scoped_lock lock(m_mutex); { while (m_writingWriters > 0 || (m_preferWriter && m_waitingWriters > 0)) { m_cond.wait(lock); } m_readingReaders++; } } void ReadUnlock() { boost::mutex::scoped_lock lock(m_mutex); { m_readingReaders--; m_preferWriter = true; m_cond.notify_all(); } } ... private: boost::mutex m_mutex; boost::condition_variable m_cond; };