Lock和Synchronized区别

来源:互联网 发布:新浪php笔试题 编辑:程序博客网 时间:2024/05/21 04:52

参考网站:
Synchronized内部原理:http://www.cnblogs.com/javaminer/p/3889023.html

1、Lock主要开销在未获得锁的线程进入等待队列阻塞上下文切换的开销,竞争不激烈时,Synchronized使用的轻量级锁和偏向锁,这两种锁都能有效减少轮询或者阻塞的发生,此时Synchronized效率会较Lock高些。
竞争激烈时,Synchronied升级为重量锁,Synchronized效率急剧下降,此时Lock效率高很多。
synchronize
受保护的代码抛出异常,JVM 将确保锁会获得自动释放
它无法中断一个正在等候获得锁的线程,也无法通过投票得到锁,如果不想等下去,也就没法得到锁
ReentrantLock:
ReentrantLock 类实现了 Lock ,它拥有与 synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性
激烈争用情况下更佳的性能(当许多线程都想访问共享资源时,JVM 可以花更少的时候来调度线程,把更多时间用在执行线程上)
lock 必须在 finally 块中释放,受保护的代码抛出异常,不会释放锁资源
Lock包含了Condition对象,每个condition都有自己的队列,所以通过不同的condition唤醒特定的线程。运行condition之前必须先持有锁资源。

高并发吞吐率:Lock非公平锁 > synchronize > Lock公平锁单线程吞吐率:synchronize > Lock非公平锁 > Lock公平锁

二、JVM中锁的优化:
1 Synchronized语法包括,a、同步语句(Synchronized(Object){}) b、同步方法 c、同步静态方法(相当于对Class同步)
2 JVM中monitorenter和monitorexit字节码依赖于底层的操作系统的Mutex Lock来实现的。使用互斥锁需要将当前线程挂起并从用户态切换到内核态来执行,这种切换的代价是非常昂贵的。
3 锁粗化(Lock Coarsening):也就是减少不必要的紧连在一起的unlock,lock操作,将多个连续的锁扩展成一个范围更大的锁。
4 锁消除(Lock Elimination):通过运行时JIT编译器的逃逸分析来消除一些没有在当前同步块以外被其他线程共享的数据的锁保护,通过逃逸分析也可以在线程本地Stack上进行对象空间的分配(同时还可以减少Heap上的垃圾收集开销)。
5 轻量级锁(Lightweight Locking):如果同步代码处于无锁竞争状态(即单线程执行环境),完全可以避免调用操作系统层面的重量级互斥锁,取而代之的是在monitorenter和monitorexit中只需要依靠一条CAS原子指令就可以完成锁的获取及释放。
当存在锁竞争的情况下,执行CAS指令失败的线程将调用操作系统互斥锁进入到阻塞状态,当锁被释放的时候被唤醒。
6 偏向锁(Biased Locking):是为了在无锁竞争的情况下避免在锁获取过程中执行不必要的CAS原子指令,因为CAS原子指令虽然相对于重量级锁来说开销比较小,但还是存在非常可观的本地延迟。
7 适应性自旋(Adaptive Spinning):当线程在获取轻量级锁的过程中执行CAS操作失败时,在进入与monitor相关联的操作系统重量级锁(mutex semaphore)前会进入忙等待(Spinning)然后再次尝试,当尝试一定的次数后如果仍然没有成功则调用与该monitor关联的semaphore(即互斥锁)进入到阻塞状态。