首页 文章

静态变量的线程安全性

提问于
浏览
14
class ABC implements Runnable {
    private static int a;
    private static int b;
    public void run() {
    }
}

我有一个如上所述的Java类 . 我有这个类的多个线程 . 在 run() 方法中,变量 ab 每次递增几次 . 在每个增量上,我将这些变量放在Hashtable中 .

因此,每个线程都会增加两个变量并将它们放在Hashtable中 . 如何使这些操作线程安全?

4 回答

  • 10

    我会使用AtomicInteger,它被设计为线程安全的并且易于使用并且给应用程序带来绝对最小的同步开销:

    class ABC implements Runnable {
        private static AtomicInteger a;
        private static AtomicInteger b;
        public void run() {
            // effectively a++, but no need for explicit synchronization!
            a.incrementAndGet(); 
        }
    }
    
    // In some other thread:
    
    int i = ABC.a.intValue(); // thread-safe without explicit synchronization
    
  • 6

    取决于什么需要线程安全 . 对于这些 int 原语,您需要将它们替换为 AtomicInteger ,或者仅在 synchronized 方法或块中使用它们 . 如果你需要让你的跨线程Hashtable线程安全,你不需要做任何事情,因为它已经同步 .

  • 2

    使用 synchronized 方法,例如

    public synchronized void increment()
    {
      a++; b++;
      // push in to hash table.
    }
    

    如果你通过单个实例访问静态,上面是好的,但是如果你有多个实例,那么你需要在一些静态对象上进行同步 - 比如(未经测试) .

    private static Object lock = new Object();
    

    在方法中

    public void increment()
    {
      synchronize(lock)
      {
        a++;b++;
        // do stuff
      }
    }
    

    注意:这些方法假设您希望在一个原子动作中增加 ab ,其他答案突出显示如何使用原子单独增加它们 .

  • 9

    我想补充一些关于这个问题答案的细节 .

    首先,OP询问:

    如何使这些操作线程安全?

    在回答这个问题之前,我们需要达到 thread safe 的一致性 . 我最喜欢的定义是来自"Java Concurrency In Practice"而且它是

    如果一个类在从多个线程访问时行为正确,则它是线程安全的,无论运行时环境是否调度或交错执行这些线程,并且调用代码没有额外的同步或其他协调 .

    如果您同意该定义,则意味着我们在进一步讨论之前达到一致性 . 让's return to the operations you meant, it' s a++b++ ,在增量之后,你将它们放入 HashTable .

    对于 a++ 操作,它实际上不是单个操作 . 它服从 read modify write 的模型 . 如您所见,它实际上包含三个单独的步骤 . 读取值,添加一个值并保存回来 . 如果有两个线程同时读取变量 a ,值为 1 ,则在修改并保存后退操作 . 该值将为 2 ,但实际上应为 3 . 为了避免这种情况发生,就像其他人建议的那样,您可以直接使用 AtomicInteger 而不是 int 类型 . AtomicInteger 将保证一些操作,如递增以原子方式执行 . 这意味着, read modify write 操作无法分割,并将作为一个单独的步骤执行 .
    之后,OP希望将值保存到HashTable中 . HashTable是一个线程安全的容器,不需要其他同步 .
    希望这个澄清可以帮助别人以其他方式 . 谢谢 .

相关问题