Java中的同步获取方法

时间:2015-10-26 18:42:47

标签: java synchronization

这可能看起来像是迂腐,但实际上我质疑我的基本假设......:)

java documentation on synchronised methods中,有以下示例:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

synchronized方法确实需要value关键字吗?当然这是原子的,是否在其他线程上对相关方法的任何调用之前或之后检索该值几乎没有区别?以下是否足够:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public int value() {
        return c;
    }
}

我理解在一个更复杂的情况下,访问多个私有变量然后是,这是必要的 - 但在这个简单的情况下,可以安全地假设这可以简化吗?

另外,我认为未来的修改可能需要将值方法同步,这可能会被遗忘,导致错误等,所以这可能有点像防御性编程,但我忽略了这个方面这里.. :))

2 个答案:

答案 0 :(得分:4)

是的,value()确实需要同步。否则,线程可以调用value()并获得陈旧的答案。

  

当然这是原子

对于整数,我相信,但如果价值是longdouble,则不是。{p}甚至可以看到字段中的一些位已更新!

  在对其他线程上的相关方法的任何调用之前或之后检索

值会产生什么影响?

取决于您的使用案例。通常它很重要。

如果value()未同步,某些静态分析软件(如FindBugs)会将此代码标记为没有正确的同步。

答案 1 :(得分:2)

从另一个线程读取和写入变量都需要

synchronized。这保证了

  1. 将值从缓存或寄存器复制到RAM(授予此权限对于写入而不是读取非常重要)

  2. 它确定写入将在读取之前发生,如果它们在代码中出现的话。否则,编译器可以自由重新排列字节码行以进行优化

  3. 检查 Effective Java 项目66以获得更详细的分析