저는 하나의 엔트리 만 가지고있는 int itemHolder에 대한 소비자 생산자 문제를 시도하고 있습니다. 나는 소비자 스레드가 항목을 넣었을 때 소비자 스레드가 제작자 스레드에 알리지 않는 이유를 모른다. 예상되는 동작은 제작자가 항목을 itemHolder에 넣을 때까지 소비자 스레드가 대기한다는 것이다. 반면에 외부 mutax 객체에서 잠금을 사용할 때 완벽하게 작동합니다. 외부 뮤텍스 예상대로이 제대로 작동 에 잠금으로여기 왜 대기/알림이 발생하지 않습니까?
public class ProducerConsumer {
public static void main(String... args) {
new ProducerConsumer().execute();
}
private volatile int itemHolder = -1; // -1 value represent that ItemHolder is empty
private void execute() {
final Thread producer = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i < 5; i++) {
synchronized (this){
while (itemHolder != -1){ // ItemHolder is full
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
itemHolder = i;
notify();
System.out.println(String.format("producer: ItemHolder has value, Consumer notified..."));
}
}
}
}, "Producer-thread");
final Thread consumer = new Thread(new Runnable() {
@Override
public void run() {
while (true){
synchronized (producer){
try {
while (itemHolder == -1){ // Don't consume if itemHolder don't have a value
producer.wait();
}
System.out.println(String.format("CONSUMER: consuming %s...", itemHolder));
itemHolder = -1; // re-initialize the itemHolder
producer.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "Consumer-thread");
consumer.start();
producer.start();
}
. 첫 번째 프로듀서, 당신은 Runnable
아니라 생산 자체 인 this
에 동기화하기 때문에
public class ProducerConsumerWithMutex {
public static void main(String... args) {
new ProducerConsumerWithMutex().execute();
}
private final String mutex = "";
private volatile int itemHolder = -1;
private void execute() {
final Thread producer = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i < 5; i++) {
synchronized (mutex){
while (itemHolder != -1){ // itemHolder is full
try {
mutex.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
itemHolder = i;
System.out.println(String.format("producer: producing %s...", i));
mutex.notify();
System.out.println(String.format("producer: Consumer notified, itemHolder has item..."));
}
}
}
}, "Producer-thread");
final Thread consumer = new Thread(new Runnable() {
@Override
public void run() {
while (true){
synchronized (mutex){
try {
while (itemHolder == -1){
System.out.println("CONSUMER: itemHolder is empty, waiting...");
mutex.wait();
}
System.out.println(String.format("CONSUMER: consuming %s...", itemHolder));
itemHolder = -1;
mutex.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "Consumer-thread");
consumer.start();
producer.start();
}
예, 뮤텍스는 Object()이어야합니다. buy 제작자 스레드를 동기화하는 방법을 알지 못했습니다. producerRunnable을 이동하면 동기화가 어떻게 발생합니까? 일어날 생산자 스레드에서? – tintin
첫 프로듀서의'synchronized (this)'는 스레드가 아닌 Runnable과 동기화됩니다. 그리고 소비자의 경우,'synchronized (producer)'를 호출하면 Runnable이 아닌 Thread에서 동기화됩니다. 그래서 두 개의 다른 자물쇠를 사용하고 있습니다. 그리고 제작자 Thread의 Runnable 인스턴스에는 이름이 없으므로 (익명 임) 이름을 지정하지 않으면 잠금으로 사용할 수 없습니다 (첫 번째 제안). – assylias
설명해 주셔서 감사합니다 :-) – tintin