论坛首页 Java企业应用论坛

最简单高效的tryLock

浏览 18570 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-09-25  
asme2u 写道
mercyblitz 写道
asme2u 写道
if(l.tryLock()) {
  try{

   // 这里能有多个线程同时到达?

  } finally {
    l.unlock
  }

}
 mercyblitz 写道
asme2u 写道
mercyblitz 写道
asme2u 写道
hellojinjie 写道
asme2u 写道

ellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???

你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。

我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高



看来是ReentrantLock 里的tryLock太耗时了,才会使得用AtomicBoolean实现的Lock性能比ReentryLock好

正解,只有符合锁占用的时间与获取锁的时间可比拟时,这个类才有意义,所以我列出了适用场景。


你要看情况,
建议楼主看一下为什么要引入偏向锁,就是为了解决CAS延迟问题。http://blogs.sun.com/dave/entry/biased_locking_in_hotspot

你所说的场景不过是你-client的设置罢了,多核CPU再来试试。

看了一下你的链接,谢谢你的提醒,确实有延迟的问题,如果这么考虑,是否CAS都不可靠了呢?这些个原子类什么时候适用?



在你的代码中,那个逻辑判断是可靠的,但是中间的执行代码是线程不安全的。

PS:CAS是可靠的,它是Wait-free的实现,不过它只能针对单个资源安全,不能作为多语句的原子操作。

 

 

 

是的,代码中没有让线程等待。

 

CAS是个原子操作,不可能被打断,那怎么可能会有两个线程执行 lock.compareAndSet(true, false)这个都返回true呢?

 

恩,你是对的,不过中间代码端的资源没有同步主存。

0 请登录后投票
   发表时间:2010-09-25  
的确,中间的那段,我们开发的时候意识到了,使用的是一个volatile变量作为标志繁忙状态而已,可能在别的场合下,中间的那段会发生CPU缓存中的变量与内存中的不一致的情况
0 请登录后投票
   发表时间:2010-09-25  
asme2u 写道
的确,中间的那段,我们开发的时候意识到了,使用的是一个volatile变量作为标志繁忙状态而已,可能在别的场合下,中间的那段会发生CPU缓存中的变量与内存中的不一致的情况


恩,volatile 还是不行,还是因为原子操作的问题。
0 请登录后投票
   发表时间:2010-09-25  
mercyblitz 写道
asme2u 写道
的确,中间的那段,我们开发的时候意识到了,使用的是一个volatile变量作为标志繁忙状态而已,可能在别的场合下,中间的那段会发生CPU缓存中的变量与内存中的不一致的情况


恩,volatile 还是不行,还是因为原子操作的问题。

volatile不支持并发修改,但是能保证修改被立刻看到,又为何不行?
不过以前在那里看到说JDK5.0前volatile实现得不好,没太关注,早不用老版本了
0 请登录后投票
   发表时间:2010-09-25   最后修改:2010-09-25
软件包 java.util.concurrent.atomic 的描述:

类的小工具包,支持在单个变量上解除锁定的线程安全编程。事实上,此包中的类可将 volatile 值、字段和数组元素的概念扩展到那些也提供原子条件更新操作的类。

楼主的这个锁和自旋锁还是有区别的,因为用户有机会定制"就算拿不到锁,我要做的事情"
0 请登录后投票
   发表时间:2010-09-25  
mxswl 写道
软件包 java.util.concurrent.atomic 的描述:

类的小工具包,支持在单个变量上解除锁定的线程安全编程。事实上,此包中的类可将 volatile 值、字段和数组元素的概念扩展到那些也提供原子条件更新操作的类。

楼主的这个锁和自旋锁还是有区别的,因为用户有机会定制"就算拿不到锁,我要做的事情"

public void lock() {
for (;;) {
if (lock.compareAndSet(true, false)) {
break;
}
try {
Thread.sleep(0, 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


模拟自旋锁,可否?
0 请登录后投票
   发表时间:2010-09-25  
asme2u 写道
mercyblitz 写道
asme2u 写道
的确,中间的那段,我们开发的时候意识到了,使用的是一个volatile变量作为标志繁忙状态而已,可能在别的场合下,中间的那段会发生CPU缓存中的变量与内存中的不一致的情况


恩,volatile 还是不行,还是因为原子操作的问题。

volatile不支持并发修改,但是能保证修改被立刻看到,又为何不行?
不过以前在那里看到说JDK5.0前volatile实现得不好,没太关注,早不用老版本了



volatile 支持并发修改,并且保证了JSL规范中定义的Happens-before关系。

但是由于它是偏续关系,所以不满足“因果一致性

比如:

volatile boolean b1;
volatile boolean b2;

如果b2依赖于b1,比如
{
   //b1可能是true或者false;
   b2 = !b1; //如果是volatile的关系,b2不确定。但是如果b1,b2在同步中,那么b1和b2的值都被锁定了。
    
}

0 请登录后投票
   发表时间:2010-09-25  
mercyblitz 写道
asme2u 写道
mercyblitz 写道
asme2u 写道
的确,中间的那段,我们开发的时候意识到了,使用的是一个volatile变量作为标志繁忙状态而已,可能在别的场合下,中间的那段会发生CPU缓存中的变量与内存中的不一致的情况


恩,volatile 还是不行,还是因为原子操作的问题。

volatile不支持并发修改,但是能保证修改被立刻看到,又为何不行?
不过以前在那里看到说JDK5.0前volatile实现得不好,没太关注,早不用老版本了



volatile 支持并发修改,并且保证了JSL规范中定义的Happens-before关系。

但是由于它是偏续关系,所以不满足“因果一致性

比如:

volatile boolean b1;
volatile boolean b2;

如果b2依赖于b1,比如
{
   //b1可能是true或者false;
   b2 = !b1; //如果是volatile的关系,b2不确定。但是如果b1,b2在同步中,那么b1和b2的值都被锁定了。
    
}


谢谢,你这么一说我明白了,如果只是对一个volatile操作就如我所说的,仅仅一个标志而已,就没问题了吧
0 请登录后投票
   发表时间:2010-09-25  
asme2u 写道
mercyblitz 写道
asme2u 写道
mercyblitz 写道
asme2u 写道
的确,中间的那段,我们开发的时候意识到了,使用的是一个volatile变量作为标志繁忙状态而已,可能在别的场合下,中间的那段会发生CPU缓存中的变量与内存中的不一致的情况


恩,volatile 还是不行,还是因为原子操作的问题。

volatile不支持并发修改,但是能保证修改被立刻看到,又为何不行?
不过以前在那里看到说JDK5.0前volatile实现得不好,没太关注,早不用老版本了



volatile 支持并发修改,并且保证了JSL规范中定义的Happens-before关系。

但是由于它是偏续关系,所以不满足“因果一致性

比如:

volatile boolean b1;
volatile boolean b2;

如果b2依赖于b1,比如
{
   //b1可能是true或者false;
   b2 = !b1; //如果是volatile的关系,b2不确定。但是如果b1,b2在同步中,那么b1和b2的值都被锁定了。
    
}


谢谢,你这么一说我明白了,如果只是对一个volatile操作就如我所说的,仅仅一个标志而已,就没问题了吧


对的,如果只有一个变量的话,也没有必要任何辅助代。



0 请登录后投票
   发表时间:2010-09-25  
有判断语句,不光只有一条修改语句
大致是这样的意思:
if(l.tryLock()) {
  if(!busyFlag) {
    busyFlag = true;
  }

  l.unlock();
}

那个标志是个volatile
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics