2016-11-20 1 views
0

나는 다양한 유형의 생산자/소비자 객체가 많은 제작자를 보유하고 있습니다. ProducerOfX, ProducerOfY, ConsumerOfX, ConsumerOfY. 생산자는 객체 (X 또는 Y)를 대기열에 넣고 관련 소비자에게 알립니다 (ProducerOfX는 ConsumerOfX에만 알립니다).생산자 소비자 - 잠글 내용

이 작업을하려면 자물쇠로 사용할 객체가 필요합니다. 내 질문은, 개체를 만들지, 예를 들어. new X()를 호출하고 ProducerOfX와 ConsumerOfX를 모두 사용하여 wait/notify를 호출합니다.

대기열이 하나만 있고 일반 개체 MyQueue를 유지하기 위해이 큐를 작성했습니다. 따라서 많은 제작자와 소비자가이 대기열을 공유합니다. X와 Y를 하나의 큐에 넣는다. X가 켜져 있으면 ConsumerOfX가 깨어나서 X가 제거됩니다. Y와 동일합니다.

대기열에서 소비자에게 '지금 X 객체가 있습니다.'또는 생산자에게 '안녕하세요, X의 소비자, 방금 X를 대기열에 넣었습니다'라고 말하십시오. 대기열의 생산자가 대기열의 소비자에 대해 알지 않아야한다고 생각합니다.

더 깨끗한 방법이 있습니까?

+0

일반적으로 사물의 알림 측면뿐만 아니라 잠금 (안전한 게시)을 처리하는 동시 대기열 구현을 사용합니다. – BeeOnRope

+0

내가 수행하려고하는 작업은 멀티 스레딩을 가르쳐 주므로 동시 패키지에서 아무 것도 사용하지 않을 것입니다. – TheCoder

+0

질문이 확실하지 않습니다. 다른 오브젝트 유형과 다른 사용자가있는 경우 두 개의 대기열을 사용하십시오. 아마도 질문을 적어도 두 가지로 나누어야합니다. 하나는 동시 대기열을 만드는 방법에 초점을 맞춘 것이고, 다른 하나는 생산/소비자 유형이 다른 하나의 대기열과 상호 작용한다는 아이디어에 관한 것입니다. 그들은 나에게 직각으로 보입니다. – BeeOnRope

답변

0

구현에 따라 다릅니다. 제품마다 다른 대기열이있는 경우 각 대기열은 개별 잠금 객체로 보호되어야합니다 (이 잠금 객체는 대기열 자체 일 수 있음).

또한 큐의 구현을 작성하는 경우에는 Lock 개체를 개인 변수로 사용할 수 있는지 여부에 따라 다릅니다. 또한 대기열이 꽉 차서 개인 잠금 변수에 wait을 갖도록 선택할 수 있는지 확인할 수 있습니다. 개체가 소비되면 개인 잠금 개체에 notifyall (또는 notify, notifyall이 바람직 함)을 호출 할 수 있습니다. 비슷한 방법으로 소비자가 비어있을 때 큐에서 요소를 가져 오는 메소드를 호출하는 경우 waitnotify 로직을 사용할 수 있습니다. 이렇게하면 큐 클래스가 private 변수 객체를 사용하여 잠금 및 알림을 처리합니다. 큐에는 private 변수 lovk 객체가 있으므로 각 큐 인스턴스에는 자체적 인 별도의 Lock 객체가 있습니다.

다른 방법은 큐가 일반 큐인 경우 큐가 작성되지 않은 것일 수 있습니다. 그러면 추가 및 페치 메소드를 호출하는 코드를 보호해야합니다. 서로 다른 제품 (x, y 등)에 대해 별도의 큐가있는 경우 각 큐에 대해 서로 다른 Lock 개체가 필요합니다. 이것은 교착 상태를 막기 위해 필요합니다. 우리는 sepatrate 잠금 객체가없는 경우 consumerX가 queueX에 요소가 삽입되기를 기다리고 (빈 상태) ​​다른 producerY가 queueY에 삽입 할 기회를 얻지 못할 수도 있습니다 (예 : 완전한). 따라서 별도의 잠금 객체가 필요합니다. 당신은 하나 개의 생산 및 제품의 동일한 유형에 intrested 모두 소비자가있는 경우

업데이트

@TheCoder는 하나의 큐는 괜찮습니다. 이제는 둘 다 통신해야하는 공유 객체에 대한 질문이옵니다. 그것은 구현에 달려 있습니다. Queue가 돌보고 싶다면 Queue는 private 필드 private Object monitor = new Object();을 가질 수 있으며, enqueuedequeue 메쏘드가`monitor '에서 동기화 될 수 있습니다.

dequeue 메서드 큐가 비어있는 경우 큐가 비어있을 때까지 while 루프 내에서 monitor.wait()을 호출하십시오. 대기열이 비어 있지 않은 경우 대기열에서 객체를 제거하고 monitor.notifyAll();

enqueue 방법은 대기열이 가득 찰 때까지 monitor.wait() 대기열이 가득 찰 때까지 호출합니다.큐가 가득 아닌 경우, 대기열에 개체를 추가하고 구현이 같은 경우 당신은 당신이 ProducrerConsumerenqueue를 호출하기 전에 동기화 할 수있는 공유 객체가 있어야 동기화 해 돌봐하지 큐 것인지를 monitor.notifyAll();

전화 queue에있는 dequeue 이 공유 객체는 queue 자체의 인스턴스가 될 수 있습니다. waitnotifyAll은 공유 객체의 synchronized 블록 내에서 호출해야합니다.

+0

대기열이 하나 있습니다. 내 편집을 참조하십시오. – TheCoder

+0

다양한 소비자와 생산자간에 하나의 대기열이 공유됩니다. 이제는 서로 다른 제품 또는 소비자를위한 소비자가 분리되어 있으며 생산자는 일반 제품입니다 (모든 소비자는 제품 X를 소비 할 수 있고 모든 생산자는 Y를 생산할 수 있음)? –

+0

단일 대기열을 갖는 것이 좋지 않을 수도 있습니다. 특정 제품의 생산자가 발생하지 않거나 생산 기회가 거의 없을 수도 있습니다. 특정 제품의 소비자에게도 마찬가지 일 수 있습니다 ... –