使用AtomicInteger替代可变的Integer是一个好的做法吗?(关于IT技术的问题)

5
我有以下的场景: 这是一段简单的代码,我在这里展示它以澄清我的疑虑:
public void callMe()
{
 AtomicInteger howManyOdds = new AtomicInteger(0);
 AtomicInteger howManyEvens = new AtomicInteger(0);
 loopThrough(100,howManyOdds,howManyEvens);
 System.out.println(howManyOdds.get()+" "+howManyEvens.get());
}
private void loopThrough(int counter,AtomicInteger howManyOdds,AtomicInteger howManyEvens)
{
 for(int i = 1 ; i <= counter ;i++)
 {
  if(i%2 == 0)
  howManyEvens.getAndAdd(1);
  else
  howManyOdds.getAndAdd(1);
 }
}

我知道可以用int[]来实现,但是看起来有点奇怪。在这种情况下,AtomicInteger是否是可替代的可变整数? 如果不是,为什么?


2
AtomicInteger是为并发而构建的。对于这种情况,取两个整数并将它们递增应该足够了。 - Amit
@Amit,根据您的说法,AtomicInteger在不涉及并发的情况下不应该使用。我的问题是为什么? - Mac
1
@Mac 这个方法有些巧妙,但是对于读者来说并不一定清晰易懂,只要它被包含在您的代码中(即私有且作为实现的一部分),我认为没有问题。但是我不会将其暴露在公共API中,并且建议使用dasblinkenlight提出的自定义对象。 - assylias
1
@Mac,性能影响是由于在AtomicInteger中使用了volatile,但将是最小的(volatile读取通常等同于非volatile读取 - volatile写入可以比非volatile写入慢几个数量级,但我们谈论的是纳秒级别)。如果您真的想使用可变结构,则int[2]将表现更好。 - assylias
1
@Mac 我在某些情况下已经这样做了,因为它比其他任何方法都更简单,并添加了注释 - 在你的情况下,因为你有两个相关的数字,使用一个类可能会提高可读性。最终,你需要问自己谁将来会阅读代码,它是否清晰易懂。这是高度主观的。 - assylias
显示剩余3条评论
1个回答

8

我认为在本质上不是并发的情况下使用AtomicInteger会误导读者,因此这不是一个好主意。

使用数组也不是一个好主意,即使从技术上讲它可以正常工作。问题在于生成的代码不太描述性,因为索引与其含义(即0表示奇数,1表示偶数)之间的“映射”在API本身中不可见。

最好使用一个可变类来保存两个属性:

public class OddEven {
    int odd, even;
    public int getOdd() {return odd;}
    public int getEven() {return even;}
    public void incOdd() {odd++;}
    public void incEven() {even++;}
}

这样可以获得非常好的可读性,而不会给人造成有些并发事情正在幕后进行的假象。

感谢您的输入。是的,我会像您在这里展示的那样做。但是,我的主要关注点是:在非并发情况下使用AtomicInteger是否是不良实践..为什么?我没有看到任何synchronization围绕AtomicXXX方法中的任何方法..它将如何影响代码的性能? - Mac
2
@Mac,关键不是性能:使用AtomicInteger的代码将尽可能高效。主要问题是如何向人类读者传达您的想法。他们会想:“为什么他要我传递AtomicInteger?我认为他的类不是并发的;我错了吗?”通常情况下,您希望避免这样的事件,因为它们使其他人难以维护您的代码。 - Sergey Kalinichenko
这是一个好的观点,我从你这里了解到了。但是,如果该方法是私有的,并且仅在该类内部使用,即使是这种情况,您也会说这是错误的做法吗?? - Mac
2
@Mac 是的,即使在那种情况下,我认为这是一种不好的做法。在某个时候,你会想要继续前进,并将你编写的代码交给其他人来维护。你不想永远维护那些代码,对吧?即使你自己没问题,你的公司可能会有一些疑虑(比如臭名昭著的“被公交车撞了”问题)。 - Sergey Kalinichenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接