2021년 목표설정

이미지
기본적으로 작년에 달성하지 못한 것들을 하려고 생각중인데..코로나가 언제까지 이어질지, 한국이나 북해도는 갈 수 있을지..자격증은 응시 가능할지..여러가지가 불확실하다. 2021년은 무엇보다 정신적인 부분과 경제적인 부분에 중점을 두고 조금 더 치열하게 지내보고 싶다. 일본나이로도 30대 마지막 해, 이제 불혹에 접어드는 나이..복잡하지만 심플하게. 육체적목표 : 트라이에슬론 스탠다드 도전하기 정신적 : 자격증2개 도전 + 자체개발 서비스 론칭 가족적 : 가정의 평화를 유지하기 경제적 : 외식과 유흥비를 줄이고 부수입을 늘려서 결과적으로 저축하기 사회적 : 목표세미나를 포함해서 민단과 개인인맥의 활성화와 교류를 촉진하기

Java Thread 예제 - Producer와 Consumer 예제

[문제정의]
Producer와 Consumer 가 있다.
한 쪽은 스택에 값을 지속적으로 저장하고(Producer), 다른 한 쪽은 스택의 값을 지속적으로 삭제한다.(Consumer)
Producer가 값을 너무 빠르게 저장하면 Stack overflow가 발생하며, 반대로 Consumer가 값을 너무 빠르게 삭제를
하게 되면 Stack underflow가 발생한다.
또한, 동시에 Stack에 접근하여 값을 쓰거나 삭제하려고 하면, 교착상태에 빠져버린다.
이를 해결하기 위해서 주어진 예제 프로그램에 Thread를 적용시켜서 Producer와 Consumer가 올바르게 작동하게
하는 프로그램으로 완성시켜라.

/*
* $Id: ProducerConsumer.java 8 2009-06-26 11:13:41Z DONG,Wooseok $
*/
import java.util.Random;
import java.lang.Thread;
import java.lang.Runnable;

/**
* BoundedBuffer class uses an array of int for a buffer. The size of
* the array is specified by the parameter of the constructor.
*/
class BoundedBuffer
{
/** bounded buffer data as array of int. first-in first-out (queue). */
private int[] buf;
private int queuePointer;
private int queueTop;

BoundedBuffer(int size)
{
buf = new int[size];
this.queuePointer = 0;
this.queueTop = size;
}
/**
* If the buffer is full, the current thread must wait.
*/
synchronized void insert(int i)
{
// implement here!
if (queuePointer == queueTop)
{
try
{
wait();
}
catch (InterruptedException e)
{
throw new RuntimeException(e.toString());
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
else
{
buf[queuePointer] = i;
queuePointer++;
notifyAll();// consumer스래드에 notifyAll() 호출
}
}
/**
* If the buffer is empty, the current thread must wait.
*/
synchronized int remove()
{
// implement here!
if (queuePointer == 0)
{
try
{
wait();
}
catch (InterruptedException e)
{
throw new RuntimeException(e.toString());
// TODO Auto-generated catch block
//e.printStackTrace();
}// wait()
}
else
{
queuePointer--;
notifyAll();
// producer 스래드에 notifyAll() 호출
// producer 스래드의 insert() 실행
}

return 0;
}
} // end of BoundedBuffer
/**
* Producer class is a thread. It always tries to insert an object (int
* value) into the bounded buffer.
*/
class Producer implements Runnable
{
/**
* A object (int value) which is inserted into the buffer. Each time
* producer calls buf.insert(), counter is incremented by one.
* counter is shared among Producer threads (static).
*/
private static int counter = 0;
/** bounded buffer reference */
private BoundedBuffer buf;
Producer(BoundedBuffer buf)
{
this.buf = buf;
}

public void run()
{
while (true)
{
buf.insert(counter++);
try
{
Thread.sleep(SleepTimer.time());
}
catch(InterruptedException e)
{
throw new RuntimeException(e.toString());
}
}
}
}
/**
* Consumer class is a thread. It always tries to remove an object (int)
* from the bounded buffer.
*/
class Consumer implements Runnable
{
/** bounded buffer reference */
private BoundedBuffer buf;
Consumer(BoundedBuffer buf)
{
this.buf = buf;
}

public void run()
{
while(true)
{
int val = buf.remove();
System.out.println("==> " + Thread.currentThread().getName() + " threadID(" + Thread.currentThread().getId()+ ") gets" + val);
try
{
Thread.sleep(SleepTimer.longtime());
}
catch(InterruptedException e)
{
throw new RuntimeException(e.toString());
}
}
}
}
/**
* SleepTimer class provides a random number (long value) which is used
* to sleep threads. All the methods are static.
*/
class SleepTimer
{
private static final Random r = new Random();
private static final int SLEEP_TIME = 100;
private static final int LONG_SLEEP_TIME = 200;
/**
* time() returns long value between 0 (inclusive) and SLEEP_TIME
* (exclusive)
*/
static long time()
{
return r.nextInt(SLEEP_TIME);
}
/**
* longtime() returns long value between 0 (inclusive) and
* LONG_SLEEP_TIME (exclusive)
*/
static long longtime()
{
return r.nextInt(LONG_SLEEP_TIME);
}
}
/**
* ProducerConsumer class instantiates Producer threads and Consumer
* threads, and lets them start.
*/
public class ProducerConsumer
{
public static void main(String[] args)
{
// implement here!
BoundedBuffer myBuffer = new BoundedBuffer(100);
Producer myProducerA = new Producer(myBuffer);
new Thread(myProducerA).start();
Producer myProducerB = new Producer(myBuffer);
new Thread(myProducerB).start();
Producer myProducerC = new Producer(myBuffer);
new Thread(myProducerC).start();
Consumer myConsumerA = new Consumer(myBuffer);
new Thread(myConsumerA).start();
Consumer myConsumerB = new Consumer(myBuffer);
new Thread(myConsumerB).start();
Consumer myConsumerC = new Consumer(myBuffer);
new Thread(myConsumerC).start();

myBuffer.insert(0);
myBuffer.remove();


}
「 커 멘 트 」


まず、Thread化した時、java.lang.thread からのinheritanceすること、java.lang.runnable
interfaceから、implementsすることがります。
私は、二つの方法を全部してみましたが、runnable interfaceimplementation しました。
queueについては、queuepointer 変数を定義して、完成させました。
insert()では、引数でもらったIを、Bufferで入れる、remove()では、queuepointerを減少させました。問題の要求と同じで、insert()する時にbufferfullのとき、wait(),反対で、remove()する時にbufferemptyのとき、exception handlingをしながら、wait()をしました。
もし、insertremoveができると、nofityAll()して、wait()している他のthreadにお知らせをしました。同期化、synchronousをため、synchronized keywordを使いました。
instanceしたとき、size 10のbufferd object一つと三つのproducer objectconsumer objectをつくりました。問題のとおりで、全部6個のTHREADSが、同期化しなから、BUFFERで動きました。
SLEEP_TIMELONG_SLEEP_TIMEを値を変化させても、 動きました。

これで要求は満足できます。

댓글

이 블로그의 인기 게시물

[메모] PostgreSQL에서 Insert 하는 경우 자동채번 PK가 중복에러 나는 경우

[C# & LINQ] 랜덤으로 데이터를 한 개 추출하는 방법

[react-native] uuid 생성이 에러가 날 때 대처법