Java – 使用AtomicInteger和Static int

在使用多个线程的时候,每当我想使用一个可由多个线程访问的计数器时,我就学会了使用静态变量。

例:

static int count=0; 然后在程序中我将它用作count++;

今天我遇到了一个名为AtomicInteger东西,我也了解到它是Thread安全的,并且可以使用一个名为getAndInrement()方法来实现相同的效果。

任何人都可以帮助我理解使用static atomicIntegerstatic int count吗?

AtomicInteger用于对整数执行primefaces操作 ,当您不想使用synchronized关键字时,它是另一种选择。

在非primefaces场上使用volatile会产生不一致的结果。

 int volatile count; public void inc(){ count++ } 

static将使该类的所有实例共享一个变量 ,但它仍然会在multithreading环境中产生不一致的结果。

因此,当您处于multithreading环境时尝试这些:

遵循布莱恩规则总是更好:

当我们编写一个接下来要被另一个线程读取的变量时,或者当我们读取一个仅由另一个线程写入的变量时,它需要被同步。 共享字段必须是私有的,这使得read和write方法/primefaces语句同步。

2.第二个选项是使用Atomic Classes ,如AtomicInteger, AtomicLong, AtomicReference, etc.

我同意@ Kumar的回答。

易失性是不够的 – 它对内存顺序有一些影响,但不能确保++的primefaces性。

multithreading编程的真正困难之处在于,任何合理数量的测试都不会出现问题。 我写了一个程序来演示这个问题,但它有一些线程除了增加计数器之外什么都不做。 即便如此,计数仍在正确答案的1%左右。 在一个真正的程序中,线程还有其他工作要做,两个线程执行++接近足以同时显示问题的可能性非常低。 无法测试multithreading正确性,必须进行设计。

该程序使用简单的静态int,volatile int和AtomicInteger执行相同的计数任务。 只有AtomicInteger始终能够得到正确的答案。 具有4个双线程内核的多处理器上的典型输出是:

 count: 1981788 volatileCount: 1982139 atomicCount: 2000000 Expected count: 2000000 

这是源代码:

  import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; public class Test { private static int COUNTS_PER_THREAD = 1000000; private static int THREADS = 2; private static int count = 0; private static volatile int volatileCount = 0; private static AtomicInteger atomicCount = new AtomicInteger(); public static void main(String[] args) throws InterruptedException { List threads = new ArrayList(THREADS); for (int i = 0; i < THREADS; i++) { threads.add(new Thread(new Counter())); } for (Thread t : threads) { t.start(); } for (Thread t : threads) { t.join(); } System.out.println("count: " + count + " volatileCount: " + volatileCount + " atomicCount: " + atomicCount + " Expected count: " + (THREADS * COUNTS_PER_THREAD)); } private static class Counter implements Runnable { @Override public void run() { for (int i = 0; i < COUNTS_PER_THREAD; i++) { count++; volatileCount++; atomicCount.incrementAndGet(); } } } } 

“static”使var成为类级别。 这意味着,如果在类中定义“static int count”,无论您为该类创建了多少个实例,所有实例都使用相同的“count”。 虽然AtomicInteger是普通类,但它只是添加了同步保护。

使用AtomicIntegerincrementAndGet()保证是primefaces的。
如果使用count++来获取先前的值,则不能保证它是primefaces的。


我错过了你的问题 – 并且通过其他答案说明 – 静态与线程无关。

static int counter会在multithreaded环境中为您提供不一致的结果,除非您使计数器volatile或使增量块synchronized

automic情况下,它为单个变量提供无lock-free thread-safe编程。

automic和链接中的更多细节

我认为没有保证在count++上看到最新的价值。 count++必须读取count的值。 另一个Thread可以编写一个新的值来count但是将它的值存储在Thread本地缓存中,即不会刷新到主内存。 你的Thread ,读取count ,没有保证从主存储器读取,即从主存储器刷新。 synchronize保证。

AtomicInteger将get和increment作为primefaces进程。 它可以被认为是数据库中的序列发生器。 它提供了实用方法来递增,递减delta int值。

如果您获得计数器然后处理然后更新它,静态int可能会导致问题。 AtomicInteger可以轻松完成,但如果您必须根据处理结果更新计数器,则无法使用它。