Java多线程增量

Java多线程增量,java,multithreading,concurrency,synchronization,Java,Multithreading,Concurrency,Synchronization,在我的申请中,我有以下几类 public class InsertErrorLinesHandler { private int currentCount; public void insertErrorLine() { //do something... currentCount++; } } 我有多个线程使用同一个insertErrorLineHandler实例,特别是调用insertErrorLine方法。在所有这些线程停止后,

在我的申请中,我有以下几类

public class InsertErrorLinesHandler {

    private int currentCount;

    public void insertErrorLine() {
        //do something...
        currentCount++;
    }
}
我有多个线程使用同一个
insertErrorLineHandler
实例,特别是调用insertErrorLine方法。在所有这些线程停止后,我从这个实例中获取
currentCount

问题是-如何重写这个类以确保不会出现任何并发问题?我想确定的是,
currentCount
value将是来自线程的方法调用计数。我应该使用静态方法和静态变量吗?使方法同步?使变量易变


谢谢

我建议使用具有线程安全增量方法的简单修复程序,使方法调用同步:

public class InsertErrorLinesHandler {

    private int currentCount;

    public void synchronized insertErrorLine() {
        //do something...
        currentCount++;
    }
}
使用或在线程数较多时使用,以获得更好的性能

下面是如何使用AtomicInteger的示例

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

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

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

到目前为止,还没有人回答你问题的这一部分:

我应该使用静态

是否使用
静态
的选择完全独立于是否使用
同步
原子整数
的选择。答案取决于你想数到什么

Java中的
静态
字段是一些其他语言所称的全局变量:整个程序只有一个全局变量。一个非静态字段(也称为实例变量)存在于多个副本中——它所属类的每个实例都有一个副本

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


如果您的程序只创建了一个
InsertErrorLineHandler
实例(即,如果您将其作为单例类使用),则不应使用
静态
。使字段
静态
或非静态不会改变单例的行为,但在单例中使用
静态
将是不好的风格。

这就是我想做的,但有人怀疑,也许有更好的方法……最好的方法通常是最简单的。其他方法包括使用一个静态对象来同步增量操作、导入几个类,甚至重写该类。明智地选择简单,是的;但是,如果
//执行某些操作…
需要花费大量时间,并且不会影响其他线程,则效率非常低。不太简单,但更理想的方法是在
currentCount++
语句周围包装一个
synchronized
块。看到您的简单修复包含一个巨大的bug,我觉得很有趣。如果不将字段标记为volatile,其他线程可能看不到更改。单靠同步并不能保证多线程的安全。@NicoVanBelle,我明白你关于使其易失性的观点,但这是否意味着在线程进入同步块并执行
currentCount++
之后,有可能
currentCount
的实际值不会写入内存?Brian Goetz的书“Java并发性在实践中”专门讨论了保持一个可从多个线程访问的计数器的问题。他的解决方案是使用
AtomicLong
。简单有效。只有一个
InsertErrorLineHandler
实例。所以我认为我没有使用
static