【问题标题】:Thread safety static variables线程安全静态变量
【发布时间】:2014-08-23 15:22:44
【问题描述】:

我读过 thread safety for static variables 我理解并同意,但是

在书中 java se 7 程序员考试 804 有人可以给我解释一下

public void run() { 
    synchronized(SharedCounter.class) { 
        SharedCounter.count++; 
    }
} 

但是,此代码效率低下,因为它获取并释放 每次加锁只是为了增加count的值。

谁能给我解释一下上面的引述

【问题讨论】:

  • 简单地说,是什么让我在上面的代码中感到困惑......“类上的同步块是否使它的静态变量不受数据竞争的影响?”
  • 安全的是总是使用同步块访问共享计数变量,并且总是使用same对象作为监视器。无论此监视器是 SharedCounter.class 还是任何其他对象都不会改变任何内容。
  • 为什么投反对票,这样我下次就可以知道我做错了什么谢谢

标签: java thread-safety


【解决方案1】:

代码并不是特别低效。它可能会更有效率。主要问题是它很脆弱:如果任何开发人员忘记同步其对全局 SharedCounter.count 变量的访问,您就会遇到线程安全问题。实际上,由于i++ 不是原子操作,并且由于在不同步的情况下更改变量的值不会使变量的新值对其他线程可见,因此对i 的每次访问都必须以同步的方式完成。

因此,同步没有正确地封装在单个类中。通常,访问全局公共字段是不好的设计。在多线程环境中情况更糟。

使用 AtomicInteger 解决了封装问题,同时稍微提高了效率。

【讨论】:

  • 也许值得注意的是i++不是原子操作,所以它需要同步。只是这在类上序列化,因此在类上同步的任何其他块,或者静态同步的方法也会阻塞。
【解决方案2】:

同步可能很昂贵,因此不应粗心使用。还有更好的方法,例如使用AtomicInteger.incrementAndGet();,它使用不同的机制来处理同步。

【讨论】:

    【解决方案3】:

    与使用可以在不使用锁的情况下进行原子增量的内部 CPU 指令相比,它的效率很低。见http://en.wikipedia.org/wiki/Fetch-and-addhttp://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html

    【讨论】:

      猜你喜欢
      • 2011-11-18
      • 1970-01-01
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      • 2014-12-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多