【发布时间】:2017-09-26 00:42:13
【问题描述】:
我正在通过这个程序,但无法理解它。
class Q
{
int n;
synchronized int get()
{
System.out.println("Got: " + n);
return n;
}
synchronized void put(int n)
{
this.n = n;
System.out.println("Put: " + n);
}
}
class Producer implements Runnable
{
Q q;
Producer(Q q)
{
this.q = q;
new Thread(this, "Producer").start(); }
public void run()
{
int i = 0;
while(true)
{ q.put(i++); }
}
}
class Consumer implements Runnable
{
Q q;
Consumer(Q q)
{
this.q = q; new Thread(this, "Consumer").start();
}
public void run() { while(true) { q.get(); } }
}
class PC
{
public static void main(String args[])
{
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
虽然 Q 上的 put( ) 和 get( ) 方法是同步的,但没有什么能阻止生产者超越消费者,也不会阻止消费者两次消费相同的队列值。因此,您会得到此处显示的错误输出:
放置:1 得到:1 得到:1 得到:1 得到:1 得到:1 放: 2 放: 3 放: 4 放: 5 放: 6 放: 7 得到:7
如您所见,生产者放1后,消费者开始连续五次得到相同的1。然后,生产者恢复并生产2到7,而没有让消费者有机会消费它们。我的问题是为什么我们会得到如此奇怪的输出,我的意思是当 get() 被执行时它返回一个值,然后线程应该从监视器中退出,而不是它停留在那里并打印 1 这么多次并且;然后 put() ,它如何能够增加和打印这些值。 ???请帮忙,我知道我可能会显得幼稚,因为我是 java 的新手。
【问题讨论】:
-
我看不出输出有什么特别奇怪的地方。这就是多线程的事情。仅仅因为一个线程放弃了监视器,并不意味着另一个线程可以立即运行。调度程序可能会在第二个线程有机会之前让第一个线程一遍又一遍地拥有监视器。
-
“低效率”从何而来。与什么相比效率低下?
-
为什么要重新实现
AtomicInteger? -
当你修复你不相关的标题时,请格式化这个烂摊子。我无法理解你的问题。
标签: java multithreading synchronization synchronized thread-synchronization