synchronized 与 lock

来源:互联网 发布:sql like 编辑:程序博客网 时间:2024/05/01 06:14


synchronized 与 lock


(1)代码层

Lock是基于在语言层面实现的锁,Lock锁可以被中断,支持定时锁。在安全的前提下,可以很随意的释放锁,如果安全的话。


Synchronized是基于JVM实现的,称之为对象的内置锁,Java中的每一个对象都可以作为锁。

1)对于同步方法,锁是当前实例对象。

2)对于静态同步方法,锁是当前对象的Class对象。

3)对于同步方法块,锁是Synchonized括号里配置的对象。当一个线程访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。


JVM基于进入和退出Monitor对象来实现方法同步和代码块同步,但两者的实现细节不一样。


代码块同步是使用monitorenter和monitorexit指令实现,而方法同步是使用另外一种方式实现的,细节在JVM规范里并没有详细说明,但是方法的同步同样可以使用这两个指令来实现。

monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束处和异常处,每个monitorenter必须有一个monitorexit对应。任何对象都有一个 monitor 与之关联,当且一个monitor 被持有后,它将处于锁定状态。

线程执行到 monitorenter 指令时,将会尝试获取对象所对应的 monitor 的所有权,即尝试获得对象的锁。

其实无论是Lock还是Synchronized,他们加锁的机制,使用的机器指令,系统调用都基本一致。

 

(2)效率上的区别

当竞争不是很激烈的时候Synchronized使用的是轻量级锁或者偏向锁,这两种锁都能有效减少轮询或者阻塞的发生,相比与Lock仍旧要将未获得锁的线程放入等待队列阻塞带来的上下文切换的开销,此时Synchronized效率会高些,当竞争激烈的时候Synchronized会升级为重量级锁,由于Synchronized的出对速度相比Lock要慢,所以Lock的效率会更高些。一般对于数据结构设计或者框架的设计都倾向于使用Lock而非Synchronized。


(3)其他

1)注意锁的粒度性


2) synchronized  锁只锁括号里面的代码内容,一个方法或者一个类等等。如果被锁的代码抛出异常会自动释                 放锁资源。


3)锁锁定 lock 和 unlock 之间的代码,被锁的代码抛出异常不会自动释放锁资源,需要 try catch  后在 finally 里

     面手动 unlock 释放锁资源


另外补充:

java之yield(),sleep(),wait()区别详解


0 0
原创粉丝点击