기본 지식
synchonized, wait(), notify(), notifyAll()을 알아야 한다. 
멀티 쓰레드 패턴은 synchonized와 wait(), notify(), notifyAll()을 적절히 사용하는 방법을 제시한다.
public synchronized void put(Object o) {
queue.addLast(o);
this.notifyAll();
}
public void put(Object o) {
synchronized(this){
          queue.addLast(o);
    this.notifyAll();
      }
}
임의의 객체에 대한 wait(), notify(), notifyAll()을 호출하기 위해서는 반드시 해당 객체에 대한 lock(synchronized)을 획득해야 한다.

Guarded Suspension 패턴
쓰레드를 기다리게 하여 인스턴스의 안정성을 지킨다. Guarded wait, spin lock이라고도 불리운다.

public class GuardedQueue {
private final LinkedList queue = new LinkedList();
public GuardedQueue() {
        }

public synchronized Object get() {
while (queue.size() <= 0) {
try {
wait();
} catch (InterruptedException e) {
}
}
return queue.removeFirst();
}

public synchronized void put(Object o) {
queue.addLast(o);
notifyAll();
}
}

자원을 제어하는 Pool에 활용할 수 있다 Ex)DB/Socket Connection, Thread Pool등등

Producer Consumer 패턴
Guarded Suspension과 다르게 버퍼를 가지고 있다.
채널의 개념을 가지고 있다.

public class Channel {
private final Object[] buffer;
private int tail;
private int head;
private int count;
public Channel(int count) {
buffer = new Object[count];
this.count = count;
}
public synchronized void put(Object cake) 
                throws InterruptedException {
while (count >= buffer.length) {
wait();
}
buffer[tail] = cake;
tail = (tail + 1) % buffer.length;
count++;
notify();
}
public synchronized Object take()  throws InterruptedException {
while (count <= 0) {
wait();
}
Object cake = buffer[head];
head = (head + 1) % buffer.length;
count--;
notify();
return cake;
}
}

Read-Write Lock 패턴 
객체에 대한 Read Lock과 Write Lock을 효과적으로 제어한다.
고비용의 리소스 제어에 활용이 가능하다.
   Read  Write
 Read  OK  충돌
 Write  충돌  충돌

public class ReadWriteLock {
private int readingReaders = 0;
private int waitingWriters = 0;
private int writingWriters = 0;
private boolean preferWriter = true; 
public synchronized void readLock() 
              throws InterruptedException {
while ( writingWriters > 0 || 
       (preferWriter && waitingWriters > 0)
     ) {
wait();
}
readingReaders++;
}
public synchronized void readUnlock() {
readingReaders--;
preferWriter = true;
notifyAll();
}
public synchronized void writeLock() throws InterruptedException {
waitingWriters++;
try {
while (readingReaders > 0 || writingWriters > 0) {
wait();
}
} finally {
waitingWriters--;
}
writingWriters++;
}
public synchronized void writeUnlock(){
writingWriters--;
preferWriter = false;
notifyAll();
}
}
abstract public class SafeAccess {
private final Object[] buffer;
private final ReadWriteLock lock = new ReadWriteLock();
public SafeAccess(int size) {
buffer = new Object[size];
}
final public Object read() throws InterruptedException {
lock.readLock();
try {
return doRead();
} finally {
lock.readUnlock();
}
}
final public void write(Object value) throws InterruptedException {
lock.writeLock();
try {
doWrite(value);
} finally {
lock.writeUnlock();
}
}
abstract protected Object doRead(); 
abstract protected void doWrite(Object value); 
}

'코딩과 개발' 카테고리의 다른 글

Java Launcher만들기  (0) 2012.09.19
The GNU C Library Reference Manual  (0) 2009.10.30
Eclipse RCP 따라하기  (1) 2009.10.26
Java ClassLoader 이해하기  (0) 2009.10.26
Posted by sjokim
,