synchronized与lock,fcpx和pr哪个效率更高高

2011年4月 Java大版内专家分月排行榜第二2010年8月 Java大版内专家分月排行榜第二2010年5月 Java大版内专家分月排行榜第二2008年2月 Java大版内专家分月排行榜第二2007年7月 Java大版内专家分月排行榜第二
2011年2月 Java大版内专家分月排行榜第三2010年9月 Java大版内专家分月排行榜第三2008年9月 Java大版内专家分月排行榜第三2008年1月 Java大版内专家分月排行榜第三2007年11月 Java大版内专家分月排行榜第三2007年9月 Java大版内专家分月排行榜第三
2011年4月 Java大版内专家分月排行榜第二2010年8月 Java大版内专家分月排行榜第二2010年5月 Java大版内专家分月排行榜第二2008年2月 Java大版内专家分月排行榜第二2007年7月 Java大版内专家分月排行榜第二
2011年2月 Java大版内专家分月排行榜第三2010年9月 Java大版内专家分月排行榜第三2008年9月 Java大版内专家分月排行榜第三2008年1月 Java大版内专家分月排行榜第三2007年11月 Java大版内专家分月排行榜第三2007年9月 Java大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。ReentrantLock比synchronized 强大在哪儿? - ITeye问答
官方说明:一个可重入的互斥锁定 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些基本行为和语义,但功能更强大。
强大在哪儿?求高人解释。
问题补充:这位大哥,你说了Lock的特性,但这些特性强大在哪儿能介绍一二否?
chenchao051 写道简单说:
1、ReentrantLock可以实现fair lock
public ReentrantLock(boolean fair) {
sync = (fair)? new FairSync() : new NonfairSync();
所谓fair lock就是看获得锁的顺序是不是和申请锁的时间的顺序是一致的
2、ReentrantLock支持中断处理
public final void acquireInterruptibly(int arg) throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
就是说那些持有锁的线程一直不释放,正在等待的线程可以放弃等待。
3、ReentrantLock可以和condition结合使用
public boolean hasWaiters(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
public int getWaitQueueLength(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
ps Synchronized的性能随着JDK版本的升级变得越来越好,到了6以后,其实也不像网上传的那样性能比ReentrantLock差很多很多。
问题补充:这位大哥,你说synchronized锁的粒度比Lock的粗,我用一下代码试了一下,
先getSrcWithSync再setSrcWithLock : set可以被执行,get线程都可以结束
先getSrcWithLock再setSrcWithSync : set不被执行,get线程都结束不了
(我这个例子貌似不太好,不结束的情况CPU就会老100%,汗!)
import java.util.concurrent.TimeU
import java.util.concurrent.locks.ReentrantL
public class TaskUseSyncAndLock {
String src = "original";
int a=2,b=1;
ReentrantLock lock = new ReentrantLock();
public synchronized String getSrcWithLock() {
boolean a = lock.tryLock();
System.out.println("Get Lock");
lock.lock();
while (true) {
if (!"original".equals(this.src)) {
System.out.println("Changed!
Now, Src = "+src);
} catch (Exception e) {
// TODO: handle exception
} finally{
lock.unlock();
public void setSrcWithLock(String src) {
boolean a = lock.tryLock();
System.out.println("Get Lock");
lock.lock();
this.src =
System.out.println("I have changed src");
} catch (Exception e) {
// TODO: handle exception
} finally{
lock.unlock();
public synchronized String getSrcWithSync() {
while (true) {
if (!"original".equals(this.src)) {
System.out.println("Changed!
Now, Src = "+src);
public synchronized void setSrcWithSync(String src) {
this.src =
* @param args
public static void main(String[] args){
final TaskUseSyncAndLock task = new TaskUseSyncAndLock();
new Thread(){
public void run(){
task.getSrcWithSync();
}.start();
TimeUnit.SECONDS.sleep(2);
System.out.println("Sleep 2s done!");
} catch (InterruptedException e) {
e.printStackTrace();
new Thread(){
public void run() {
task.setSrcWithLock("Love");
}.start();
问题补充:freish 写道synchronized锁的粒度比Lock的粗
举个简单的例子:
1、Lock的某些方法可以决定多长时间内尝试获取锁,如果获取不到就抛异常,这样就可以一定程度上减轻死锁的可能性,如果锁被另一个线程占据了,synchronized只会一直等待,很容易错序死锁
2、synchronized的话,锁的范围是整个方法或synchronized块部分;而Lock因为是方法调用,可以跨方法,灵活性更大
3、便于测试,单元测试时,可以模拟Lock,确定是否获得了锁,而synchronized就没办法了
谢谢大侠。。。
但是你提到的三点好像都没有说明锁的粒度这个方面把?
采纳的答案
回楼主,其实提到了,Synchronized只能在方法或者块上加锁,而lock可以只对某条语句进行加锁。
再回楼主,您说的没有特别指出ReentrantLock的好处,其实我列举的三点应该都比较明显了:
1、在某些场合下,确实需要获得锁的时间与申请锁的时间相一致,但是Synchronized做不到。
2、如果不支持中断处理,那么线程可能一直无限制的等待下去,就算那些正在占用资源的线程死锁了,正在等待的那些资源还是会继续等待,但是ReentrantLock可以选择放弃等待。
3、关于Condition这个强大的特性都可以另开一贴了,建议仔细查看API。
引用ReentrantLock实现了Lock接口。获得ReentrantLock的锁与进入synchronized块具有相同的语义,释放ReentrantLock锁与退出synchronized块有相同的语义。相比于synchronized,ReentrantLock提供了更多的灵活性来处理不可用的锁。下面具体来介绍一下ReentrantLock的使用。
1. 实现可轮询的锁请求
在内部锁中,死锁是致命的——唯一的恢复方法是重新启动程序,唯一的预防方法是在构建程序时不要出错。而可轮询的锁获取模式具有更完善的错误恢复机制,可以规避死锁的发生。
如果你不能获得所有需要的锁,那么使用可轮询的获取方式使你能够重新拿到控制权,它会释放你已经获得的这些锁,然后再重新尝试。可轮询的锁获取模式,由tryLock()方法实现。此方法仅在调用时锁为空闲状态才获取该锁。如果锁可用,则获取锁,并立即返回值true。如果锁不可用,则此方法将立即返回值false。此方法的典型使用语句如下:
Lock lock = ...;
if (lock.tryLock()) {
try {
// manipulate protected state
} finally {
lock.unlock();
}
} else {
// perform alternative actions
}
2. 实现可定时的锁请求
当使用内部锁时,一旦开始请求,锁就不能停止了,所以内部锁给实现具有时限的活动带来了风险。为了解决这一问题,可以使用定时锁。当具有时限的活
动调用了阻塞方法,定时锁能够在时间预算内设定相应的超时。如果活动在期待的时间内没能获得结果,定时锁能使程序提前返回。可定时的锁获取模式,由tryLock(long, TimeUnit)方法实现。
3. 实现可中断的锁获取请求
可中断的锁获取操作允许在可取消的活动中使用。lockInterruptibly()方法能够使你获得锁的时候响应中断。
引用当ReentrantLock被加入到Java 5.0中时,它提供的性能要远远优于内部锁。如果有越多的资源花费在锁的管理和调度上,那用留给应用程序的就会越少。更好的实现锁的方法会使用更少的系统调用,发生更少的上下文切换,在共享的内存总线上发起更少的内存同步通信。耗时的操作会占用本应用于程序的资源。Java 6中使用了经过改善的管理内部锁的算法,类似于ReentrantLock使用的算法,从而大大弥补了可伸缩性的不足。因此ReentrantLock与内部锁之间的性能差异,会随着CPU、处理器数量、高速缓存大小、JVM等因素的发展而改变。
PS:以上摘自&java并发编程实践&
简单说:
1、ReentrantLock可以实现fair lock
public ReentrantLock(boolean fair) {
sync = (fair)? new FairSync() : new NonfairSync();
所谓fair lock就是看获得锁的顺序是不是和申请锁的时间的顺序是一致的
2、ReentrantLock支持中断处理
public final void acquireInterruptibly(int arg) throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
就是说那些持有锁的线程一直不释放,正在等待的线程可以放弃等待。
3、ReentrantLock可以和condition结合使用
public boolean hasWaiters(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
public int getWaitQueueLength(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
ps Synchronized的性能随着JDK版本的升级变得越来越好,到了6以后,其实也不像网上传的那样性能比ReentrantLock差很多很多。
synchronized锁的粒度比Lock的粗
举个简单的例子:
1、Lock的某些方法可以决定多长时间内尝试获取锁,如果获取不到就抛异常,这样就可以一定程度上减轻死锁的可能性,如果锁被另一个线程占据了,synchronized只会一直等待,很容易错序死锁
2、synchronized的话,锁的范围是整个方法或synchronized块部分;而Lock因为是方法调用,可以跨方法,灵活性更大
3、便于测试,单元测试时,可以模拟Lock,确定是否获得了锁,而synchronized就没办法了
已解决问题
未解决问题synchronized 和 lock - 永远的未来 - ITeye技术网站
博客分类:
首先,先明确下synchronized的几个关键点:
A.无论synchronized关键字加在方法上还是对象上,他取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。
B.每个对象只有一个锁(lock)和之相关联。
C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
synchronized可以加在方法上,也可以加在对象上,通常理解为,只有持有了锁才可以进行对应代码块的执行。
java.util.concurrent.locks包下面提供了一些锁的实现,有读写锁,公平锁等。
将synchronized替换成lock的实现可以提升性能:
1. 大部分应用场景是读写互斥,写和写互斥,读和读不互斥。而synchronized则是都互斥。
可以利用读写锁来优化性能,读锁锁住读的代码块,写锁锁住写的代码块。
2. 要确保你在理解原来利用到synchronized的代码逻辑,避免一概而论地把synchronized替换成锁。
public void getPair(){
return "x="+x + ",y="+y;
//这个函数
public synchronized void
increment() {
getPair();
//可以替换成
public void
increment() {
lock.lock();
getPair();
lock.unlock();
//但是,如果getPair()是synchronized
public synchronized void getPair(){
return "x="+x + ",y="+y;
//还能替换这个函数吗?
public synchronized void
increment() {
getPair();
//这时候就不能简单地使用lock来替换了,这里要调用getPair();必需申请到对象锁,这个时候increment也要竞争这把锁
//因此这里的代码效果是读写互斥。
//如果只是用lock来锁住increment,则达不到效果。还得同时锁getPair();
//这里嵌套了synchronized,而synchronized的嵌套结构中在同一个对象的方法上是共享一把锁的。
//上面只是简单的例子,java编程思想的多线程编程中有更详细的这个例子,有兴趣的可以看看。
浏览: 75577 次
来自: 上海
623deyingxiong 写道请问,比如说我在程序中第一次 ...
请问,比如说我在程序中第一次new 一个类的实例时,这个类的C ...
小子还不错!
盛大的点点滴滴点点滴滴点点滴滴滴滴

我要回帖

更多关于 synchronized lock 的文章

 

随机推荐