Java多线程增量可能是否定的?

时间:2016-12-02 07:46:17

标签: 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() ...

1 个答案:

答案 0 :(得分:1)

可悲的是,在执行多线程程序时, 要关心线程安全性。使用++操作递增long不是原子操作也不是线程安全的...转到Ted Hopp在评论中建议的AtomicLongincrementAndGet() ...