我試圖用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();
}
時鎖定,在外部互斥 預期這正常工作。
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()。購買我沒有得到如何同步生產者線程。如何移出producerRunnable會導致同步。在生產線上發生? – tintin
你的第一個生產者中的'synchronized(this)'在Runnable上同步,而不是在Thread上。而在你的消費者中,當你調用'synchronized(producer)'時,你在線程上同步而不是在Runnable上運行。所以你正在使用兩個不同的鎖。由於生產者Thread中的Runnable實例沒有名稱(匿名),因此除非您給它起一個名字(我的第一個提議),否則您無法將其用作鎖。 – assylias
感謝您的澄清:-) – tintin