在优化一些锁定内容的同时,我使用了JMH基准测试,以了解锁定一个锁定的ReentrantLock比只锁定一次要花费多少成本.当我看到jdk11比jdk21表现得更好时,我很惊讶……如果能理解为什么以及我的基准测试是否正确,那将是一件非常好的事情.
我还添加了带有同步块的Benchmark,并且根本没有任何锁定.正如预期的那样,同步块得到了优化,其性能几乎与无锁块一样,并且不同的JDK版本之间没有降级.
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(1)
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class LockNoLockBenchmark {
int counter;
ReentrantLock lock = new ReentrantLock();
@Benchmark
public void noLock() {
++counter;
}
@Benchmark
public void syncLock() {
synchronized (new Object()) {
++counter;
}
}
@Benchmark
public void lockUnlock() {
lock.lock();
try {
++counter;
} finally {
lock.unlock();
}
}
@Benchmark
public void lockLockUnlockUnlock() {
lock.lock();
try {
lock.lock();
try {
++counter;
} finally {
lock.unlock();
}
} finally {
lock.unlock();
}
}
}
在Intel Rocket Lake(酷睿i9)第12代英特尔(R)酷睿(TM)i9-12950HX 12核64 GB RAM上运行
- JDK 21
openjdk 21.0.2 2024-01-16
OpenJDK Runtime Environment (build 21.0.2+13-58)
OpenJDK 64-Bit Server VM (build 21.0.2+13-58, mixed mode, sharing)
Benchmark Mode Cnt Score Error Units
LockNoLockBenchmark.lockLockUnlockUnlock avgt 10 27.457 ± 0.876 ns/op
LockNoLockBenchmark.lockUnlock avgt 10 11.409 ± 0.256 ns/op
LockNoLockBenchmark.noLock avgt 10 0.280 ± 0.010 ns/op
LockNoLockBenchmark.syncLock avgt 10 0.280 ± 0.008 ns/op
- JDK 11
openjdk 11.0.21 2023-10-17
OpenJDK Runtime Environment (build 11.0.21+9-post-Ubuntu-0ubuntu122.04)
OpenJDK 64-Bit Server VM (build 11.0.21+9-post-Ubuntu-0ubuntu122.04, mixed mode, sharing)
Benchmark Mode Cnt Score Error Units
LockNoLockBenchmark.lockLockUnlockUnlock avgt 10 22.414 ± 1.366 ns/op
LockNoLockBenchmark.lockUnlock avgt 10 11.690 ± 0.407 ns/op
LockNoLockBenchmark.noLock avgt 10 0.283 ± 0.021 ns/op
LockNoLockBenchmark.syncLock avgt 10 0.289 ± 0.012 ns/op
我希望在使用JDK 21的情况下,性能不会下降. 我还感兴趣的是,当我需要获取一个锁定的锁时,有哪些方法可以优化代码. 谢谢