同步(这个)和几个同步的类方法之间的区别

时间:2017-06-06 22:58:35

标签: java synchronized

在编程访谈中暴露的书籍(Wrox出版物),生产者消费者问题的代码对名为IntBuffer的类中的每个produce()和consume()方法使用'synchronized'关键字。这与在每个方法中使用synchronized(this)不同吗?该书说,“当一个线程忙于在produce()中等待时,没有线程可以进入consume(),因为方法是同步的。”我觉得这对书中的代码没有意义,因为当一个线程忙于在produce()中等待时,没有线程可以进入produce()。然而,其他线程可以进入consume(),这破坏了互斥的想法。产生和消费的方法应该完全同步吗?

书中的代码:

public class IntBuffer
{
    private int index;
    private int[] buffer = new int[8];

    // Function called by producer thread
    public synchronized void produce(int num) {
        while(index == buffer.length - 1) {
            try { wait();}
            catch(InterruptedException ex) {}
        }
        buffer[index++] = num;
        notifyAll();
    }

    // Function called by consumer thread
    public synchronized int consume() {
        while(index == 0) {
            try { wait();}
            catch(InterruptedException ex) {}
        }
        int ret = buffer[--index];
        notifyAll();
        return ret;
    }
}

4 个答案:

答案 0 :(得分:3)

不,他们是一样的。

private synchronized void foo() {}

private void foo2() {
 synchronized(this){
 }
}

它们将完全相同,同时监视它们的调用实例。

在Jakob Jenkov的博客中可以找到一个好的教程 http://tutorials.jenkov.com/java-concurrency/synchronized.html#java-synchronized-example

快乐的编码!

答案 1 :(得分:0)

问:这与在每个方法中使用synchronized(this)不同吗? 答:不,它没有什么不同,通过使用块(同步(this)你可以只同步部分代码,而不是整个方法。 例如:

public void m1(){
// some code
synchronized(this){ 
// thread-safe code 
}

答案 2 :(得分:0)

  

这与在每个方法中使用synchronized(this)不同吗?

没有

  

这本书说,“当一个线程忙于在produce()中等待时,没有线程可以进入consume(),因为方法是同步的。”我觉得这对书中的代码没有意义,因为当一个线程忙于在produce()中等待时,没有线程可以进入produce()。然而,其他线程可以进入consume(),这会破坏相互排斥的想法。

这不正确。两个方法都在同一个对象上同步,因此只有一个线程可以在任一个方法中,除非调用wait(),它会释放锁。

  

生产和消费的方法应该完全同步吗?

是的,你说他们是。不清楚你在这里问的是什么。

答案 3 :(得分:0)

使用synchronized(this)要求调用线程采用与使用方法上的synchronized修饰符调用实例方法时相同的锁定。生成什么字节码存在一些差异,但这是一个相当低级别的区别。

synchronized关键字的目的是保护共享状态不受并发访问的影响。产品和消费方法使用相同的内部状态,因此它们都受到同一个锁的保护是合理的。

发布的代码看起来做得很好,我唯一的挑剔是我会让方法抛出InterruptedException而不是捕获它。 produce和consume方法都需要调用线程获取正在调用该方法的实例上的锁。