Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的同步Get方法_Java_Synchronization - Fatal编程技术网

Java中的同步Get方法

Java中的同步Get方法,java,synchronization,Java,Synchronization,这可能看起来很迂腐,但实际上是我在质疑我的基本假设:) 在中,有以下示例: public class SynchronizedCounter { private int c = 0; public synchronized void increment() { c++; } public synchronized void decrement() { c--; } public synchronized int

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

在中,有以下示例:

public class SynchronizedCounter {
    private int c = 0;

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

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

    public synchronized int value() {
        return c;
    }
}
value
方法是否确实需要
synchronized
关键字?当然这是原子性的,在调用其他线程上的相关方法之前还是之后检索该值没有什么区别?下列各项是否足够:

public class SynchronizedCounter {
    private int c = 0;

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

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

    public int value() {
        return c;
    }
}
我知道在更复杂的情况下,如果访问多个私有变量,那么是的,这将是必要的-但在这个简单的情况下,是否可以安全地假设这可以简化


此外,我认为未来的修改可能需要同步value方法,这可能会被遗忘,导致bug等,因此这可能在某种程度上被视为防御编程,但我在这里忽略了这一方面:)

是的,在
value()
上确实需要同步。否则,线程可以调用
value()
,得到一个过时的答案

这肯定是原子弹

对于整数,我相信是这样的,但如果值是一个
long
double
,则不是。甚至可以只看到字段中的一些位被更新

在调用其他线程上的相关方法之前或之后检索值并没有什么区别

取决于您的用例。这通常很重要


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

是的,在
value()
上确实需要同步。否则,线程可以调用
value()
,得到一个过时的答案

这肯定是原子弹

对于整数,我相信是这样的,但如果值是一个
long
double
,则不是。甚至可以只看到字段中的一些位被更新

在调用其他线程上的相关方法之前或之后检索值并没有什么区别

取决于您的用例。这通常很重要


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

从另一个线程读取和写入变量都需要同步。这保证了

  • 值将从缓存或寄存器复制到RAM(这对于写入而不是读取非常重要)

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


  • 检查有效的Java项目66以获得更详细的分析

    从另一个线程读取和写入变量都需要同步。这保证了

  • 值将从缓存或寄存器复制到RAM(这对于写入而不是读取非常重要)

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


  • 查看有效的Java Item 66以获得更详细的分析

    ,但可以肯定的是,哪个线程首先访问它是有点随意的,只要值不正确?我同意,对于需要超过1个周期才能获取的多字值,这可能不是一个原子操作,在这种情况下,它是必需的。我假设在体系结构上获取int是原子的,没有同步,JVM就可以进行各种优化。例如,假设您有一个循环
    while(counter.get()==0){/*wait或某物*/}
    。您可能期望另一个线程上的增量会释放该锁,对吗?如果getter没有同步,JVM可以(并且经常会)优化getter以从本地寄存器读取,因此永远不会看到任何增量。但是,哪个线程首先访问它肯定是任意的,只要值不错误?我同意,对于需要超过1个周期才能获取的多字值,这可能不是一个原子操作,在这种情况下,它是必需的。我假设在体系结构上获取int是原子的,没有同步,JVM就可以进行各种优化。例如,假设您有一个循环
    while(counter.get()==0){/*wait或某物*/}
    。您可能期望另一个线程上的增量会释放该锁,对吗?如果getter没有同步,JVM可以(并且通常会)优化getter以从本地寄存器读取数据,因此永远不会看到任何增量。