我编写了一个代码来查看Java中的Producer Consumer关系,如下所示。 虽然程序工作正常但我看到输出不一致。 有人可以说明以下不一致的原因。
class ProdCons2
{
public static void main (String [] args)
{
Shared s = new Shared ();
new Producer (s).start ();
new Consumer (s).start ();
}
}
class Shared
{
private char c = '\u0000';
private boolean writeable = true;
synchronized void setSharedChar (char c)
{
while (!writeable)
try
{
wait ();
}
catch (InterruptedException e) {}
this.c = c;
writeable = false;
notify ();
}
synchronized char getSharedChar ()
{
while (writeable)
try
{
wait ();
}
catch (InterruptedException e) { }
writeable = true;
notify ();
return c;
}
}
class Producer extends Thread
{
private Shared s;
Producer (Shared s)
{
this.s = s;
}
public void run ()
{
for (char ch = 'A'; ch <= 'Z'; ch++)
{
try
{
Thread.sleep ((int) (Math.random () * 1000));
}
catch (InterruptedException e) {}
s.setSharedChar (ch);
System.out.println (ch + " produced by producer.");
}
}
}
class Consumer extends Thread
{
private Shared s;
Consumer (Shared s)
{
this.s = s;
}
public void run ()
{
char ch;
do
{
try
{
Thread.sleep ((int) (Math.random () * 1000));
}
catch (InterruptedException e) {}
ch = s.getSharedChar ();
System.out.println (ch + " consumed by consumer.");
}
while (ch != 'Z');
}
}
它给了我如下输出:
A produced by producer.
A consumed by consumer.
B produced by producer.
B consumed by consumer.
C produced by producer.
C consumed by consumer.
D produced by producer.
D consumed by consumer.
E produced by producer.
F produced by producer.
E consumed by consumer.
F consumed by consumer.
G produced by producer.
G consumed by consumer.
H produced by producer.
I produced by producer.
H consumed by consumer.
I consumed by consumer.
J produced by producer.
J consumed by consumer.
K produced by producer.
L produced by producer.
K consumed by consumer.
L consumed by consumer.
M produced by producer.
M consumed by consumer.
N produced by producer.
N consumed by consumer.
O produced by producer.
O consumed by consumer.
P produced by producer.
Q produced by producer.
P consumed by consumer.
Q consumed by consumer.
R produced by producer.
R consumed by consumer.
S produced by producer.
S consumed by consumer.
T produced by producer.
T consumed by consumer.
U produced by producer.
U consumed by consumer.
V produced by producer.
V consumed by consumer.
W consumed by consumer.
W produced by producer.
X produced by producer.
X consumed by consumer.
Y consumed by consumer.
Y produced by producer.
Z produced by producer.
Z consumed by consumer.
观察P和Q处的输出:
P produced by producer.
Q produced by producer.
P consumed by consumer.
Q consumed by consumer.
控制台不打印的原因是什么:
P produced by producer.
P consumed by consumer.
Q produced by producer.
Q consumed by consumer.
答案 0 :(得分:3)
日志记录语句不是同步部分的一部分。因此,完成这一系列事件是完全可能的:
产生你观察到的输出。
如果您希望在生产之后始终记录消耗,那么日志记录语句应该在代码的同步部分内。
答案 1 :(得分:1)
而不是编写wait() / notify()
使用JDK中的标准并发类:BlockingQueue
接口非常适合多线程环境中的Consumer / Producer。