当前位置: 首页 > 科技观察

Java延迟案例分析:LockvsSynchronized

时间:2023-03-11 23:20:05 科技观察

本文通过实例讨论:-java.concurrent.Lock造成的垃圾-Lock和synchronized的比较-如何编程计算延迟-Lock和synchronized的竞争影响-对结果可能产生的影响由于延迟测试中的协调遗漏回到我最喜欢的主题之一:垃圾创建和分配。关于这个主题的更多细节可以从我之前的文章中获得(例如:FirstRulesofPerformanceOptimization和FirstRulesofPerformanceOptimization:TheEffectofEscapeAnalysis)。特别是,理解为什么在涉及性能问题时分配是一个如此重要的因素。前几天,我在诊断JIT编译时一些奇怪的分配问题时,发现java.util.concurrent.locks.ReentrantLock分配错误,但只是在竞争条件下。(这很容易证明,只需运行一个测试程序(如下所示),在Lock上建立竞争并指定--verbosegc参数)。例子是Lock竞争时GC的输出结果:[GC(AllocationFailure)16384K->1400K(62976K),0.0016854secs][GC(AllocationFailure)17784K->1072K(62976K),0.0011939secs][GC(AllocationFailure))17456K->1040K(62976K),0.0008452secs][GC(AllocationFailure)17424K->1104K(62976K),0.0008338secs][GC(AllocationFailure)17488K->1056K(61952K),0.0008K799secs][GC)0K(Allocation4244(61952K),0.0010529secs][GC(AllocationFailure)17408K->1161K(61952K),0.0012381secs][GC(AllocationFailure)17545K->1097K(61440K),0.0004592secs][GC(AllocationFailure1629K>1450sec0),6195.0sec0][GC(AllocationFailure)17001K->1129K(61952K),0.0003857secs]我怀疑是否有必要在垃圾回收时清理Lock上分配的空间。在竞争激烈的环境中,它会选择一个比内置的'synchronized'更差的同步策略。当然,这个问题比其他任何问题都更具学术性。如果您真的关心延迟,您会发现自己永远不会(或永远不应该)遇到需要这么多线程锁的情况。但是,请继续和我一起探讨这个问题,因为过程和结果都很有趣。简史:2004年在Java1.5中引入了锁。锁和其他并发工具的诞生源于对简单并发结构的迫切需求。在此之前,您必须通过内置的synchronized和Object的wait()和notify()方法来控制并发。ReentrantLock提供了许多比同步更好的特性,这里有一些例子:非结构化——例如,不受块或方法的约束,允许您跨多个方法持有锁。轮询锁等待锁超时配置失败策略但是他们在延迟测试中做了什么?我写了一个简单的测试来比较Lock和synchronized的性能。此代码允许更改线程数(1个线程表示无争用)和争用量。通过协调遗漏和无遗漏来衡量。使用Lock或synchronized来运行测试。为了记录结果,我使用了直方图类。这个类是由PeterLawrey创建的。您可以在Chronicle-Core的实用程序类中找到此类。importorg.junit.Test;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;publicclassLockVsSync{privatestaticfinalbooleanCOORDINATED_OMISSION=Boolean.getBoolean("coordinatedOmission");//要么运行testingLock要么testingsynchronizedprivatestaticfinalbooleanIS_LOCK=Boolean.getLock""isBoolean");privatestaticfinalintNUM_THREADS=Integer.getInteger("numThreads");@Testpublicvoidtest()throwsInterruptedException{Locklock=newReentrantLock();for(intt=0;t