Your SlideShare is downloading. ×
0
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Multithread design pattern
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Multithread design pattern

3,854

Published on

0 Comments
13 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,854
On Slideshare
0
From Embeds
0
Number of Embeds
10
Actions
Shares
0
Downloads
68
Comments
0
Likes
13
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Multithread Design Pattern ohyecloudy http://ohyecloudy.com 아꿈사 http://cafe.naver.com/architect1.cafe
  • 2. 기초적인 멀티쓰레드 디자인 패턴을 다룬 책이 책에 나온 내용을 요약 발표
  • 3. Single Threaded Execution 이 다리를 건널 수 있는 사람은 오직 한 명ImmutableGuarded SuspensionBalkingProducer-ConsumerRead-Write LockThread-Per-MessageWorker ThreadFutureC++::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 ExecutionImmutable 망가뜨리고 싶어도 망가지지 않는다.Guarded SuspensionBalkingProducer-ConsumerRead-Write LockThread-Per-MessageWorker ThreadFutureC++::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 ExecutionImmutableGuarded Suspension 준비가 될 때까지 기다려 주세요.BalkingProducer-ConsumerRead-Write LockThread-Per-MessageWorker ThreadFutureC++::Boost
  • 19. Guarded 보호받고 있다.Suspension 일시 정지함처리해도 될 때까지 기다린다. guarded wait, spin lock, busy wait
  • 20. // immutablepublic 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 ExecutionImmutableGuarded SuspensionBalking 필요 없으면 관둬요Producer-ConsumerRead-Write LockThread-Per-MessageWorker ThreadFutureC++::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 ExecutionImmutableGuarded SuspensionBalkingProducer-Consumer 내가 만들고 당신이 사용한다.Read-Write LockThread-Per-MessageWorker ThreadFutureC++::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 ExecutionImmutableGuarded SuspensionBalkingProducer-ConsumerRead-Write Lock 다 같이 읽는 것은 상관없지만 읽는 중간에 쓰면 안돼요.Thread-Per-MessageWorker ThreadFutureC++::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 ExecutionImmutableGuarded SuspensionBalkingProducer-ConsumerRead-Write LockThread-Per-Message 이 일을 부탁해요Worker ThreadFutureC++::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 ExecutionImmutableGuarded SuspensionBalkingProducer-ConsumerRead-Write LockThread-Per-MessageWorker Thread 일이 올 때까지 기다리고, 일이 오면 작업한다.FutureC++::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 ExecutionImmutableGuarded SuspensionBalkingProducer-ConsumerRead-Write LockThread-Per-MessageWorker ThreadFuture 먼저 교환권을 받으세요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 ExecutionImmutableGuarded SuspensionBalkingProducer-ConsumerRead-Write LockThread-Per-MessageWorker ThreadFutureC++::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;};

×