汇算清缴在哪个网站做,qwins是哪个网站做的,公司主页是什么,wordpress 来源统计java锁实现我们都将第三方库用作开发的正常部分。 通常#xff0c;我们无法控制其内部。 JDK随附的库是一个典型示例。 这些库中的许多库都使用锁来管理争用。 JDK锁具有两种实现。 一个使用原子CAS样式指令来管理索赔过程。 CAS指令往往是最昂贵的CPU指令类型#xff0c;并且… java锁实现 我们都将第三方库用作开发的正常部分。 通常我们无法控制其内部。 JDK随附的库是一个典型示例。 这些库中的许多库都使用锁来管理争用。 JDK锁具有两种实现。 一个使用原子CAS样式指令来管理索赔过程。 CAS指令往往是最昂贵的CPU指令类型并且在x86上具有内存排序语义。 锁通常是无竞争的这会导致可能的优化从而可以使用避免使用原子指令的技术将锁偏向无竞争的线程。 这种偏向使得理论上的锁定可以被同一线程快速重新获得。 如果该锁最终被多个线程争用则该算法将从被偏向的状态恢复并使用原子指令退回到标准方法。 偏向锁定已成为Java 6的默认锁定实现 。 在遵守单一作者原则时偏向锁定应该是您的朋友。 最近当使用套接字API时我决定测量锁定成本并对结果感到惊讶。 我发现我的无竞争线程所产生的开销比锁期望的要多。 我汇总了以下测试以比较Java 6中当前可用的锁实现的成本。 考试 为了进行测试我将在锁中增加一个计数器并增加锁中竞争线程的数量。 对于Java可用的3种主要锁实现将重复此测试 Java语言监视器上的原子锁定 Java语言监视器上的偏向锁定 Java 5中随java.util.concurrent包引入的ReentrantLock 。 我还将在最新的3代Intel CPU上运行测试。 对于每个CPU我将执行测试直到核心计数将支持的最大并发线程数。 该测试是在64位LinuxFedora Core 15和Oracle JDK 1.6.0_29上进行的。 代码 import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.CyclicBarrier;import static java.lang.System.out;public final class TestLocks implements Runnable
{public enum LockType { JVM, JUC }public static LockType lockType;public static final long ITERATIONS 500L * 1000L *1000L;public static long counter 0L;public static final Object jvmLock new Object();public static final Lock jucLock new ReentrantLock();private static int numThreads;private static CyclicBarrier barrier;public static void main(final String[] args) throws Exception{lockType LockType.valueOf(args[0]);numThreads Integer.parseInt(args[1]);runTest(numThreads); // warm upcounter 0L;final long start System.nanoTime();runTest(numThreads);final long duration System.nanoTime() - start;out.printf(%d threads, duration %,d (ns)\n, numThreads, duration);out.printf(%,d ns/op\n, duration / ITERATIONS);out.printf(%,d ops/s\n, (ITERATIONS * 1000000000L) / duration);out.println(counter counter);}private static void runTest(final int numThreads) throws Exception{barrier new CyclicBarrier(numThreads);Thread[] threads new Thread[numThreads];for (int i 0; i threads.length; i){threads[i] new Thread(new TestLocks());}for (Thread t : threads){t.start();}for (Thread t : threads){t.join();}}public void run(){try{barrier.await();}catch (Exception e){// dont care}switch (lockType){case JVM: jvmLockInc(); break;case JUC: jucLockInc(); break;}}private void jvmLockInc(){long count ITERATIONS / numThreads;while (0 ! count--){synchronized (jvmLock){counter;}}}private void jucLockInc(){long count ITERATIONS / numThreads;while (0 ! count--){jucLock.lock();try{counter;}finally{jucLock.unlock();}}}
} 编写测试脚本 设置-x 对于{1..8}中的i 做Java -XX-UseBiasedLocking TestLocks JVM $ i; 做完了 对于{1..8}中的i 做Java -XX UseBiasedLocking TestLocks JVM $ i; 做完了 对于{1..8}中的i 做Java TestLocks JUC $ i; 做完了 结果 图1 图2 图3 在现代英特尔处理器上偏置锁定不再应该是默认的锁定实现。 我建议您使用-XX-UseBiasedLocking JVM选项来衡量应用程序和实验的性能以确定是否可以从无竞争情况下使用基于原子锁的算法中受益。 观察结果 在无竞争的情况下有偏锁比原子锁贵10。 似乎对于最近的CPU代来说原子指令的成本比偏向锁的必要内务处理要少。 在Nehalem之前锁定指令会在内存总线上声明一个锁定以执行这些原子操作每个操作都将花费100个以上的周期。 从Nehalem开始原子指令可以在CPU内核本地进行处理并且在执行内存排序语义时不需要等待存储缓冲区为空时通常只需花费10-20个周期。 随着争用的增加无论线程数如何语言监视器锁定都会Swift达到吞吐量限制。 与使用同步的语言监视器相比ReentrantLock提供了最佳的无竞争性能并且随着争用的增加扩展性也显着提高。 当2个线程竞争时ReentrantLock具有降低性能的奇怪特征。 这值得进一步调查。 当竞争线程数较少时Sandybridge遭受原子指令增加的延迟 这在上一篇文章中已详细介绍。 随着竞争线程数的不断增加内核仲裁的成本趋于占主导地位而Sandybridge在提高内存吞吐量方面显示出其优势。 结论 在开发自己的并发库时如果无锁替代算法不是可行的选择则建议使用ReentrantLock而不是使用synced关键字因为它在x86上具有明显更好的性能。 更新2011年11月20日 Dave Dice指出未对JVM启动的前几秒中创建的锁实施偏向锁。 我将在本周重新运行测试并发布结果。 我收到了更多质量反馈表明我的结果可能无效。 微型基准测试可能会很棘手但是在大型环境中衡量自己的应用程序的建议仍然存在。 考虑到Dave的反馈可以在此后续博客中查看测试的重新运行。 参考来自我们的JCG合作伙伴 Martin Thompson的Java锁实现来自Mechanical Sympathy博客。 翻译自: https://www.javacodegeeks.com/2012/07/java-lock-implementations.htmljava锁实现