Java - 多线程增量

Java - multithreading increment

我的申请中有以下 class

public class InsertErrorLinesHandler {

    private int currentCount;

    public void insertErrorLine() {
        //do something...
        currentCount++;
    }
}

而且我有多个线程使用相同的 InsertErrorLinesHandler 实例,特别是调用 insertErrorLine 方法。在所有这些线程停止后,我从这个实例中得到 currentCount

问题是 - 如何重写此 class 以确保不会出现任何并发问题?我想要的是确保 currentCount 值将是线程方法调用的计数。我应该使用静态方法和静态变量吗?使方法同步?使变量易变?

谢谢!

我建议使用 AtomicInteger,它具有线程安全的增量方法

简单修复,使方法调用同步:

public class InsertErrorLinesHandler {

    private int currentCount;

    public void synchronized insertErrorLine() {
        //do something...
        currentCount++;
    }
}

当线程数更多时使用AtomicInteger or use LongAdder以获得更好的性能。

这里是关于如何使用 AtomicInteger 的例子,

public class InsertErrorLinesHandler {
   AtomicInteger counter = new AtomicInteger();

   public void insertErrorLine() {
       counter.incrementAndGet();
   }

   public int get() {
       return counter.get();
   }
}

到目前为止,还没有人解决您问题的这一部分:

Should I use static...?

是否使用static的选择完全独立于是否使用synchronizedAtomicInteger的选择。答案取决于你想算什么。

Java 中的一个 static 字段是某些其他语言所称的 全局 变量:整个程序只有一个。一个非静态字段(a.k.a,一个实例变量)存在于多个副本中——一个副本对应它所属的class的每个实例。

您的程序创建了多少个 InsertErrorLineHandler class 实例?如果不止一个,那么您是希望每个实例都有自己的 counter,还是希望所有实例都共享相同的 counter?声明字段 static 意味着它们将共享相同的字段,省略 static 关键字意味着每个实例将有自己的计数器。

如果您的程序只创建一个 InsertErrorLineHandler 实例(即,如果您将其用作 单例 class),那么您不应该使用static。使字段 static 或非静态不会改变单例的行为,但在单例中使用 static 将是一种糟糕的风格。