Java多线程自增可以为负数吗?

标签 java concurrency

我编写了简单的线程安全组件,用于测量多线程应用程序的性能,类似于Java配置文件工具。这个想法是n层节点树,每个节点是分析应用程序调用的方法的统计数据,并且位于执行树相应的级别和相应父级下。统计信息有几个计数器,其中之一是调用次数,调用方法时,调用次数会随着每次执行而增加。目前我不太关心胎面安全,因此计数器只有简单的长类型和由运算符++ 完成的增量。下面我放置一个代码示例。 现在的问题是:应用程序工作几个小时后,一些计数器变为负值。即使某些踏板同时增加相同的计数器,你知道会发生什么吗? 它发生在RAD环境中IBM的Java 7下。我在 Oracle 的 Java 8 下运行了类似的应用程序,但没有发生。

class Node<T>{
Node parent; 
  Map<T, Node> children = new ConcurrentHashMap<T, Node>();
Stats stats = new Stats();
Node(Node parent) { this.parent = parent;  }
void checkIn(){ stats.checkIn(); }
void checkout(){ stats.checkout(); }
}
class Stats{
  long start, time, calls; 
  void checkIn(){ ...  calls++;}
  void checkout(){ ... }
}
class ExecutionTree<T>{
     static Map<Long, ExecutionTree> inst = new ConcurrentHashMap<Long, ExecutionTree>();
    Node<T> currentNode; 
static  ExecutionTreeProfiler getInstance(){
    return inst.get(Tread.currentTread().getId());
}
void checkIn(T key){ 
  // actual code is more thread-safe, but I wrote here for simplyfy it as not relevant to question
   Node<T> child =
  currentNode.children.contains(key)? 
  currentNode.children.get(key) :new Node<T>(current node);

  currentNode.children.put(key, child); 
   child.checkin();
   currentNode = child; 
}
void checkout(T key) {
   current node.checkout();
   currentNode = currentNode.parent; 
}
≠======== measuring application ========
...
void someMethod1(){
  ExecutionTree.getInstance().checkIn("method1");
.....
ExecutionTree.getInstance().checkOut();
}
…someMethod2() ...

最佳答案

遗憾的是,在执行多线程程序时,您必须关心线程安全。使用++ 操作递增 long 不是原子操作,也不是线程安全的...请使用 Ted Hopp 在评论中建议的 AtomicLongincrementAndGet()。 ..

关于Java多线程自增可以为负数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40927184/

相关文章:

java - 拆分 ("\\") 和错误

java - 什么是好的 android 反汇编器,可以产生有用的结果

java - 如何使用 Docx4J 为 pdf 输出设置字体

java - 在 ConcurrentLinkedQueue 源代码中无法获取此条件

java - H2 服务器在调试时挂起

java - 自动配置数据源失败: 'spring.datasource.url' is not specified

java - 使用PreparedStatements时SQL Server死锁

java - 将参数传递给 Java.util.Concurrent 中的 Call 方法

java - 在没有 IllegalMonitorStateException 的情况下解锁 ReentrantLock

java - Object.wait() 无需在 JVM 中旋转