监视Java应用程序上的锁争用

我试图创建一个小的基准(在Groovy中),显示几个同步方法的高线程争用。 监控自愿上下文切换时应该出现高争用,而在Linux中,这可以通过“pidstat”来实现。

该计划如下:

class Res { private int n; synchronized public void inc() { n++; def foo = [] for (int i = 0; i < 1000; ++i) foo << "hello" } synchronized public int getN() { return n; } } while (true) { Res res = new Res() int N = 100000 for (int i = 0; i < N; ++i) { new Thread({ res.inc() if (res.getN() == N) { println "ok" } }).start() } while (res.getN() < N) { } println "=========================" } 

但命令

 pidstat -w -I -p 26848 5 

在自愿上下文切换列上打印0。 该程序创建100000个线程,同时访问同步方法。 我无法相信,有了这样的工作量,就不会发生上下文切换。

我的基准测试有什么问题?

您的命令仅显示主线程的统计信息,不计算子PID。

Hotspot JVM有内部同步计数器,但需要一些魔法来解锁它们:

  1. 运行jconsole.exe -J-Djconsole.showUnsupported并连接到您的JVM。
  2. 从主菜单中选择Connection – > Hotspot MBeans – > Create
  3. MBeans选项卡上打开sun.management.HotspotRuntime
  4. 你会在InternalRuntimeCounters属性下找到一堆计数器:
    • sun.rt._sync_ContendedLockAttempts
    • sun.rt._sync_Parks
    • sun.rt._sync_Notifications
    • sun.rt._sync_Inflations
      等等