静态变量的线程安全性

hos*_*ney 14 java multithreading thread-safety

class ABC implements Runnable {
    private static int a;
    private static int b;
    public void run() {
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Boh*_*ian 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
Run Code Online (Sandbox Code Playgroud)


Ale*_*rov 9

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


Nim*_*Nim 6

使用synchronized方法,例如

public synchronized void increment()
{
  a++; b++;
  // push in to hash table.
}
Run Code Online (Sandbox Code Playgroud)

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

private static Object lock = new Object();
Run Code Online (Sandbox Code Playgroud)

在方法中

public void increment()
{
  synchronize(lock)
  {
    a++;b++;
    // do stuff
  }
}
Run Code Online (Sandbox Code Playgroud)

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