java - 这种结构有意义吗?
问题描述
面对一个带有此代码的项目:
public class IndexUpdater implements Runnable {
@Override
public void run() {
final AtomicInteger count = new AtomicInteger(0);
FindIterable<Document> iterable = mongoService.getDocuments(entryMeta, null, "guid");
iterable.forEach(new Block<Document>() {
@Override
public void apply(final Document document) {
count.incrementAndGet();
// A lot of code....
if (count.get() / 100 * 100 == count.get()) {
LOG.info(String.format("Processing: %s", count.get()));
}
}
});
}
}
这里我对三行代码感兴趣:
if (count.get() / 100 * 100 == count.get()) {
LOG.info(String.format("Processing: %s", count.get()));
}
考虑到多线程和 AtomicInteger 变量的类型,这种情况是否有意义?或者这是一个毫无意义的检查?有趣的是,IntellijIdea 并没有强调这种结构毫无意义。
解决方案
我不会称这段代码“毫无意义”,而是错误的(或者,它可能具有意想不到的语义)。
如果这是以多线程方式调用的,则方法中的三个调用不会总是获得相同的值count.get()
(如果包含,则有四个count.incrementAndGet()
)。
在这种情况下,这样做的后果看起来并不是灾难性的——您可能会错过一些日志记录语句,并且您可能会看到一些意想不到的消息,例如Processing 101
,然后想知道为什么这个数字不是 100 的倍数。但也许如果您在其他地方使用相同的结构,会有更重要的影响。
将结果count.incrementAndGet()
放入变量 (*) 中,以便以后使用。
但是,它也会更容易使用count.get() % 100 == 0
:
int value = count.incrementAndGet();
// A lot of code....
if (value % 100 == 0) {
LOG.info(String.format("Processing: %s", value));
}
这是正确的(或者,它可能是预期的)并且更容易阅读。
(*) 根据您实际希望在此日志消息中显示的内容,您可能希望count.incrementAndGet()
在“大量代码”之后放置。
推荐阅读
- android - 是否可以在 Android.MK 中使用“minifyenabled = true”或任何替代品
- javascript - 如何确保 BackHandler 不会为同一事件加倍?
- vba - Range.Cells.Count 与 Range.Count
- r - r 绘制时间序列以汇总多个变量
- yii2 - 如何在yii2中全局声明行为方法
- angular - 无法从 Safari 的缓存中删除文件
- regex - 正则表达式匹配需要在第一次出现文件扩展名时停止并忽略其余部分
- javascript - 函数式编程 javascript 链过滤器操作默认值
- webpack - 有没有办法在苗条的组件中使用 pugjs?
- php - Cake php查询限制,返回起始记录无和总无记录