除了在 Java 中使用参数外,在方法调用之间传递数据的最有效方法是什么?

What is the most efficient way to pass data between method invocations except using parameters in Java?

我正在为一个特定的测试目的检测一个 Android 项目。我希望在方法调用之间传递一些信息(例如 infoObj 对象)。所以基本思想是在调用方法之前使用一个映射(由线程 id 索引以避免并发问题)来存储 infoObj,然后在调用开始时从映射中检索 infoObj方法体。

例如,这里有两个方法 f1f2,其中 f1 调用 f2.

void f1() {
  f2();
}

void f2() {
}

检测后,它们变成:

void f1() {
  map.put(threadID, infoObj); // put infoObj into the map before invoking f2
  f2();
}

void f2() {
  map.remove(threadID); // get infoObj from the map at the beginning of f2
}

在大多数情况下效果很好。但是,当方法调用发生在一个长循环中时,经过检测的程序的运行速度会比其原始程序慢得多。使用参数传递是最好的解决方案,但不幸的是我不能修改方法定义,因为程序语义可能会改变。

实现我的目标最有效的解决方案是什么?

在 Java 中并没有很好的方法来做到这一点。主要问题是,如果你有多个线程,你需要一个地图,而地图的使用成本适中,因为它们必须计算哈希值并在内部数据结构中定位项目。

请注意 HashMap 也不是 thread-safe。你还没有说你是否让它安全(例如,使用 Collections.synchronizedMap)。如果你有,那么你最好使用 ConcurrentHashMap,它比同步的 HashMap 快得多。如果你还没有,让它 thread-safe 只会让它变慢。

顺便说一句,ThreadLocal 有自己的内部自定义地图实现。我想这样做是为了提高性能,而且它一定比使用 HashMap 更快(否则何必呢?)。所以为什么你认为它变慢是一个谜,除非你没有同步,这可能解释它。

我可以提出一些建议:

  1. 您可以通过预测您所在的线程来避免这个问题。我不是 Android 方面的专家,但通常某些代码只能在某些线程中,而且可能不会很多 multi-threading 都在进行,除非是您自己发起的。如果是这种情况,您可以为该 code-point 创建一个特定的静态并直接引用它。
  2. 如果您无法避免使用地图,您可以在互联网上搜索更快的地图实现。
  3. 你能在别处做put操作吗?写入地图是最慢的部分,所以如果你可以 pre-populate 它用于线程,那可能会加快速度。您也不希望在检测代码中分配内存(调用 new),因此请确保每次调用时 infoObj 为 pre-allocated 和 re-use。