【问题标题】:synchronization on single statement?在单个语句上同步?
【发布时间】:2012-03-29 00:09:21
【问题描述】:

如果我有一个只有这样一个语句的 getter 方法

public class NumberClass{
    int number;

    public int getNumber() {
        return number;
    }
    ...
}

多线程访问这个方法,我必须同步这个方法还是没有必要,因为它只有一个语句??

【问题讨论】:

    标签: java multithreading synchronization


    【解决方案1】:

    我必须同步这个[get]方法或者它没有必要,因为它只有一个语句??

    它与 1 个或多个语句无关。这取决于该值是否已在另一个线程中更新,以及您是否希望所有线程都看到一致的值。

    如果 number 字段在 thread1 中更新,则 thread2 可能会获得原始值或新值,具体取决于更新的同步方式。要正确发布值,set 和 get 方法都需要synchronized

    如果您只是尝试共享 int 值,则将 number 字段标记为 volatile 将起作用,或者使用 AtomicInteger 在多个线程之间可靠地共享值可能更合适。

    private volatile int number;
    

    或使用:

    private AtomicInteger number = new AtomicInteger();
    

    【讨论】:

    • 我也有与同步here 相关的类似问题,我在套接字对象上使用同步,我想看看我是否可以通过其他有效的方式完全摆脱同步?想看看你能不能帮忙。
    • 他做到了@DavidSchwartz。评论中有他的问题的链接。
    【解决方案2】:

    是的,同步该语句可能是个好主意。原因是,根据规范,每个线程都可以缓存自己的变量版本。要演示它,请查看this answer

    其他选项是

    • 使变量可变:

      volatile int number;
      
    • 或者使用 java.util.concurrent 包中的AtomicInteger

      AtomicInteger number;
      

    附带说明:如果 number 的类型为 long,那么即使是变量的 读取 也不会是原子的(一个线程可以在阅读的中间)。请参阅 Java 语言规范的 Chapter 17.7: Non-atomic Treatment of double and long

    【讨论】:

      【解决方案3】:

      您需要一个内存屏障,否则无法保证其他线程看到“正确”的值(即明确分配给 number 的任何值)。

      要解决此问题,请将number 声明为finalvolatile 成员,或从synchronized 块访问它。

      声明的数量,与其他一些答案相反,一个考虑因素。您不需要原子性(因为它是单个语句),因此使用 synchronized 可能是矫枉过正。如果值发生变化,使用volatile,如果没有变化,使用final。如果您有多个语句需要以原子方式显示,synchronized 将是唯一的选择。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-06
        • 1970-01-01
        • 1970-01-01
        • 2020-01-18
        • 2015-05-21
        • 2012-12-08
        • 1970-01-01
        相关资源
        最近更新 更多