java:同步方法的低效率

时间:2017-04-28 02:30:48

标签: java multithreading synchronization synchronized thread-synchronization

我正在阅读这个程序并且无法理解它。

    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后,消费者开始并连续五次获得相同的内容。然后,制作人恢复并制作2到7而不让消费者有机会消费它们。我问题是为什么我们得到这样奇怪的输出,我的意思是当执行get()时它返回一个值然后线程应该从监视器退出,而不是它停留在那里并打印1次这样;然后put(),它是如何增加和打印这些值的。 ???请帮助,我知道我可能看起来很幼稚,因为我是java的新手。

2 个答案:

答案 0 :(得分:1)

os调度程序决定执行哪个线程以及哪个线程获得锁定。它不必在线程之间交替进行针锋相对,它只是确保没有因为缺少cpu片而饿死。因此,你可以看到一个线程运行一段时间,然后另一个线程有机会。让线程有一段时间的权限可以帮助最小化上下文切换。每次调度程序切换正在运行的线程都会产生开销时,最好让线程有机会运行并完成某些操作而不是在它们之间进行抖动。

如果您希望线程在严格的交替中工作,那么您可以通过让线程等待直到Q处于有效状态来强制执行该操作:

class Q {
    Integer n; // nullable
    public synchronized int get() {
        while (n == null) {
            wait();
        }
        notifyAll();
        System.out.println("got: " + n);
        int retval = n;
        n = null;
        return retval;
    }
    public synchronized void put(int n) {
        while (n != null) {
            wait();
        }
        notifyAll();
        this.n = n;
        System.out.println("put: " + n);
    }
}

此版本的Q将导致两个线程轮流。

如果您只希望线程放置并设置值而不交替,那么使用AtomicInteger会更简单。同步用于组合多个动作,以便它们不会受到其他线程的干扰。

答案 1 :(得分:1)

首先,您应该清楚生产者/消费者算法。 https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem

内森休斯回答肯定是你在找什么。