- 浏览: 4498 次
- 性别:
- 来自: 北京
最近访客 更多访客>>
文章分类
最新评论
-
daly1987:
确实不错,项目上也在用,用AtomicInteger也可以的
最简单高效的tryLock -
beneo:
asme2u 写道mercyblitz 写道asme2u 写道 ...
最简单高效的tryLock -
asme2u:
mercyblitz 写道asme2u 写道有判断语句,不光只 ...
最简单高效的tryLock -
mercyblitz:
asme2u 写道有判断语句,不光只有一条修改语句
大致是这样 ...
最简单高效的tryLock -
asme2u:
有判断语句,不光只有一条修改语句
大致是这样的意思:
if(l ...
最简单高效的tryLock
import java.util.concurrent.atomic.AtomicBoolean; /** * @author asme2u */ public class Lock { private AtomicBoolean lock = new AtomicBoolean(true); public boolean tryLock() { return lock.compareAndSet(true, false); } public void unlock() { lock.set(true); } }
原理:CAS
优点:
速度快,约是ReentrantLock的2-3倍
缺点:
需JDK5.0+
无条件对象且不可重入
未获取锁时直接调用unlock不抛IllegalMonitorStateException所以代码必须严格保证获取锁后才能调用unlock
适用场景:
不需要条件对象且当ReentrantLock的tryLock影响了你的性能的时候
我的应用场景:
最近项目中通信程序中的客户端的socket长连接的连接池,客户端使用连接具有高并发但占用连接时间非常短的特点,使用这个类代替ReentrantLock,性能提高了3倍左右
评论
23 楼
wkoffee
2010-09-25
我自己测下来用synchronized关键字更快,我想应该是这种spin lock有很多cas操作都是无效的,cas本身也是代价很大的。
22 楼
rocketball
2010-09-25
我在Linux上测试过了,也是10%左右。版本:
Linux version 2.6.18-164.el5 (mockbuild@builder10.centos.org) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)) #1 SMP Thu Sep 3 03:28:30 EDT 2009
JDK1.6 8核16G内存
Linux version 2.6.18-164.el5 (mockbuild@builder10.centos.org) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)) #1 SMP Thu Sep 3 03:28:30 EDT 2009
JDK1.6 8核16G内存
21 楼
asme2u
2010-09-25
chenlixun 写道
asme2u 写道
rocketball 写道
我在我电脑上做了一个测试,两者差别没有楼主说的那么大,前者之比后者提高10%左右,我看了下JDK1.6的API源码
前者调用方法:
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
后者调用方法:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
两者的源码并没有本质区别呀,所以为什么会有lz描述的那种情况,而我测试也没有这种情况,我CPU 双核,Windows
前者调用方法:
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
后者调用方法:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
两者的源码并没有本质区别呀,所以为什么会有lz描述的那种情况,而我测试也没有这种情况,我CPU 双核,Windows
我在公司里的开发环境(XP,双核)上测试确实是10%左右,但在CentOS X86_64 5.4 4核的服务器上跑上面的那个测试程序,大概相差2倍多,在家里的笔记本上xp, 单核的大概也是2倍多,刚才我也翻了下JDK1.6的代码,发现确实没有什么本质区别,我想原因可能在于我的测试程序(第一页里)和我的应用环境(加锁,判断,如果符合条件修改一个标志位,然后解锁)中从获取锁到释放锁的操作非常快以至于tryLock本身的操作所占的比重比较大。至于双核的XP上为什么只有10%,没想明白
顺便说一下, 你是不是以前没写个并发程序? 你有没有看CPU占用率, 这代码像是病毒, 程序一启来, CPU马上100% ,一直下不来, 直到程序结束.
这测试代码有问题, 不能这样干, 这样的测试不可靠不可信.
我写的并发程序也许为你服务过,这个测试程序一看就知道会占CPU100%,还用测试?这个测试不可靠,那也请你写一段测试程序来比较速度吧!
20 楼
chenlixun
2010-09-25
asme2u 写道
rocketball 写道
我在我电脑上做了一个测试,两者差别没有楼主说的那么大,前者之比后者提高10%左右,我看了下JDK1.6的API源码
前者调用方法:
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
后者调用方法:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
两者的源码并没有本质区别呀,所以为什么会有lz描述的那种情况,而我测试也没有这种情况,我CPU 双核,Windows
前者调用方法:
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
后者调用方法:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
两者的源码并没有本质区别呀,所以为什么会有lz描述的那种情况,而我测试也没有这种情况,我CPU 双核,Windows
我在公司里的开发环境(XP,双核)上测试确实是10%左右,但在CentOS X86_64 5.4 4核的服务器上跑上面的那个测试程序,大概相差2倍多,在家里的笔记本上xp, 单核的大概也是2倍多,刚才我也翻了下JDK1.6的代码,发现确实没有什么本质区别,我想原因可能在于我的测试程序(第一页里)和我的应用环境(加锁,判断,如果符合条件修改一个标志位,然后解锁)中从获取锁到释放锁的操作非常快以至于tryLock本身的操作所占的比重比较大。至于双核的XP上为什么只有10%,没想明白
顺便说一下, 你是不是以前没写个并发程序? 你有没有看CPU占用率, 这代码像是病毒, 程序一启来, CPU马上100% ,一直下不来, 直到程序结束.
这测试代码有问题, 不能这样干, 这样的测试不可靠不可信.
19 楼
asme2u
2010-09-25
rocketball 写道
我在我电脑上做了一个测试,两者差别没有楼主说的那么大,前者之比后者提高10%左右,我看了下JDK1.6的API源码
前者调用方法:
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
后者调用方法:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
两者的源码并没有本质区别呀,所以为什么会有lz描述的那种情况,而我测试也没有这种情况,我CPU 双核,Windows
前者调用方法:
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
后者调用方法:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
两者的源码并没有本质区别呀,所以为什么会有lz描述的那种情况,而我测试也没有这种情况,我CPU 双核,Windows
我在公司里的开发环境(XP,双核)上测试确实是10%左右,但在CentOS X86_64 5.4 4核的服务器上跑上面的那个测试程序,大概相差2倍多,在家里的笔记本上xp, 单核的大概也是2倍多,刚才我也翻了下JDK1.6的代码,发现确实没有什么本质区别,我想原因可能在于我的测试程序(第一页里)和我的应用环境(加锁,判断,如果符合条件修改一个标志位,然后解锁)中从获取锁到释放锁的操作非常快以至于tryLock本身的操作所占的比重比较大。至于双核的XP上为什么只有10%,没想明白
18 楼
chenlixun
2010-09-25
rocketball 写道
我在我电脑上做了一个测试,两者差别没有楼主说的那么大,前者之比后者提高10%左右,我看了下JDK1.6的API源码
前者调用方法:
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
后者调用方法:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
两者的源码并没有本质区别呀,所以为什么会有lz描述的那种情况,而我测试也没有这种情况,我CPU 双核,Windows
前者调用方法:
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
后者调用方法:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
两者的源码并没有本质区别呀,所以为什么会有lz描述的那种情况,而我测试也没有这种情况,我CPU 双核,Windows
同意楼上的, 以下是我分别在JDK5和JDK6下做的测试.
测试环境:
os: Windows XP Professional 2002 sp3;
cpu: Pentium(R) Dual-Core CPU E5300 @ 2.60GHz 2.60GHz;
mem: 2G;
测试结果如下:
JDK5
Lock:
300000000
57359
ReentrantLock:
300000000
56625
JDK6
Lock:
300000000
40734
ReentrantLock:
300000000
55453
LZ , 你测试的结果也贴出来看看.
17 楼
rocketball
2010-09-25
我在我电脑上做了一个测试,两者差别没有楼主说的那么大,前者之比后者提高10%左右,我看了下JDK1.6的API源码
前者调用方法:
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
后者调用方法:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
两者的源码并没有本质区别呀,所以为什么会有lz描述的那种情况,而我测试也没有这种情况,我CPU 双核,Windows
前者调用方法:
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
后者调用方法:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
两者的源码并没有本质区别呀,所以为什么会有lz描述的那种情况,而我测试也没有这种情况,我CPU 双核,Windows
16 楼
asme2u
2010-09-25
<div class="quote_title">
<pre name="code" class="java">if(l.tryLock()) {
try{
// 这里能有多个线程同时到达?
} finally {
l.unlock
}
}</pre>
mercyblitz 写道</div>
<div class="quote_div">
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<div class="quote_title">mercyblitz 写道</div>
<div class="quote_div">
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<div class="quote_title">hellojinjie 写道</div>
<div class="quote_div">
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<br><div class="quote_title">ellojinjie 写道</div>
<div class="quote_div">性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关??? <br><br>你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。</div>
<br>我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高 <br><br><br>
</div>
<br>看来是ReentrantLock 里的tryLock太耗时了,才会使得用AtomicBoolean实现的Lock性能比ReentryLock好</div>
<br>正解,只有符合锁占用的时间与获取锁的时间可比拟时,这个类才有意义,所以我列出了适用场景。 <br>
</div>
<br><br>你要看情况, <br>建议楼主看一下为什么要引入偏向锁,就是为了解决CAS延迟问题。<a href="http://blogs.sun.com/dave/entry/biased_locking_in_hotspot" target="_blank">http://blogs.sun.com/dave/entry/biased_locking_in_hotspot</a> <br><br>你所说的场景不过是你-client的设置罢了,多核CPU再来试试。</div>
<br>看了一下你的链接,谢谢你的提醒,确实有延迟的问题,如果这么考虑,是否CAS都不可靠了呢?这些个原子类什么时候适用?</div>
<br><br><br>在你的代码中,那个逻辑判断是可靠的,但是中间的执行代码是线程不安全的。 <br><br>PS:CAS是可靠的,它是Wait-free的实现,不过它只能针对单个资源安全,不能作为多语句的原子操作。</div>
<p> </p>
<p> </p>
<pre name="code" class="java">if(l.tryLock()) {
try{
// 这里能有多个线程同时到达?
} finally {
l.unlock
}
}</pre>
mercyblitz 写道</div>
<div class="quote_div">
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<div class="quote_title">mercyblitz 写道</div>
<div class="quote_div">
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<div class="quote_title">hellojinjie 写道</div>
<div class="quote_div">
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<br><div class="quote_title">ellojinjie 写道</div>
<div class="quote_div">性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关??? <br><br>你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。</div>
<br>我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高 <br><br><br>
</div>
<br>看来是ReentrantLock 里的tryLock太耗时了,才会使得用AtomicBoolean实现的Lock性能比ReentryLock好</div>
<br>正解,只有符合锁占用的时间与获取锁的时间可比拟时,这个类才有意义,所以我列出了适用场景。 <br>
</div>
<br><br>你要看情况, <br>建议楼主看一下为什么要引入偏向锁,就是为了解决CAS延迟问题。<a href="http://blogs.sun.com/dave/entry/biased_locking_in_hotspot" target="_blank">http://blogs.sun.com/dave/entry/biased_locking_in_hotspot</a> <br><br>你所说的场景不过是你-client的设置罢了,多核CPU再来试试。</div>
<br>看了一下你的链接,谢谢你的提醒,确实有延迟的问题,如果这么考虑,是否CAS都不可靠了呢?这些个原子类什么时候适用?</div>
<br><br><br>在你的代码中,那个逻辑判断是可靠的,但是中间的执行代码是线程不安全的。 <br><br>PS:CAS是可靠的,它是Wait-free的实现,不过它只能针对单个资源安全,不能作为多语句的原子操作。</div>
<p> </p>
<p> </p>
15 楼
phoenixup
2010-09-25
hellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
单核是没有提高,但是。。。现在单核的运行环境也不太常见。。所以,楼主这个帖子是可行的。。。
14 楼
xly_971223
2010-09-25
hellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
jdk5后的并发包中的类基本都是基于自旋锁实现的
也有叫CAS的
以上是个人理解
13 楼
mercyblitz
2010-09-24
asme2u 写道
mercyblitz 写道
asme2u 写道
hellojinjie 写道
asme2u 写道
ellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
你用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的实现,不过它只能针对单个资源安全,不能作为多语句的原子操作。
12 楼
asme2u
2010-09-24
mercyblitz 写道
asme2u 写道
hellojinjie 写道
asme2u 写道
ellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高
看来是ReentrantLock 里的tryLock太耗时了,才会使得用AtomicBoolean实现的Lock性能比ReentryLock好
正解,只有符合锁占用的时间与获取锁的时间可比拟时,这个类才有意义,所以我列出了适用场景。
你要看情况,
建议楼主看一下为什么要引入偏向锁,就是为了解决CAS延迟问题。http://blogs.sun.com/dave/entry/biased_locking_in_hotspot
你所说的场景不过是你-client的设置罢了,多核CPU再来试试。
看了一下你的链接,谢谢你的提醒,确实有延迟的问题,如果这么考虑,是否CAS都不可靠了呢?这些个原子类什么时候适用?
11 楼
mercyblitz
2010-09-24
asme2u 写道
hellojinjie 写道
asme2u 写道
ellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高
看来是ReentrantLock 里的tryLock太耗时了,才会使得用AtomicBoolean实现的Lock性能比ReentryLock好
正解,只有符合锁占用的时间与获取锁的时间可比拟时,这个类才有意义,所以我列出了适用场景。
你要看情况,
建议楼主看一下为什么要引入偏向锁,就是为了解决CAS延迟问题。http://blogs.sun.com/dave/entry/biased_locking_in_hotspot
你所说的场景不过是你-client的设置罢了,多核CPU再来试试。
10 楼
mercyblitz
2010-09-24
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<div class="quote_title">mercyblitz 写道</div>
<div class="quote_div">
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<pre name="code" class="java">import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author asme2u
*/
public class Lock {
private AtomicBoolean lock = new AtomicBoolean(true);
public boolean tryLock() {
return lock.compareAndSet(true, false);
}
public void unlock() {
lock.set(true);
}
}</pre>
<p> </p>
<p>原理:CAS</p>
<p> </p>
<p>优点:</p>
<p> 速度快,约是ReentrantLock的2-3倍</p>
<p> </p>
<p> 缺点:</p>
<p> 需JDK5.0+</p>
<p> 无条件对象且不可重入</p>
<p> 未获取锁时直接调用unlock不抛IllegalMonitorStateException所以代码必须严格保证获取锁后才能调用unlock</p>
<p> </p>
<p>适用场景:</p>
<p> 不需要条件对象且当ReentrantLock的tryLock影响了你的性能的时候</p>
<p> </p>
<p>我的应用场景:</p>
<p> 最近项目中通信程序中的客户端的socket长连接的连接池,客户端使用连接具有高并发但占用连接时间非常短的特点,使用这个类代替ReentrantLock,性能提高了3倍左右</p>
</div>
<p> </p>
<p> </p>
<p>你这个有线程安全问题呢,怎么保证在tryLock 和unlock之间的线程安全(状态一直性)?</p>
<p> </p>
<p>ReentrantLock 是利用Thread 队列,只有独占线程看到共享资源,pack其他线程,待操作完毕,下一个线程unpack继续操作。同时还有JVM底层的操作。</p>
<p> </p>
<p> </p>
</div>
<p>如果任何线程使用都遵守tryLock返回true后再去unlock,不会有线程安全问题的,compareAndSet是个原子操作</p>
</div>
<p> </p>
<p> </p>
<p>我的天啊, 在同步(互斥)中间执行的代码叫做“临界区”,AtomicX类都是Nonblocking的,怎么取保其他线程不进入“临界区”,这个不算的话。线程安全,还应该保证 Thread的读和写的数据和主存中的一致。你这个类怎么取保?</p>
<div class="quote_div">
<div class="quote_title">mercyblitz 写道</div>
<div class="quote_div">
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<pre name="code" class="java">import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author asme2u
*/
public class Lock {
private AtomicBoolean lock = new AtomicBoolean(true);
public boolean tryLock() {
return lock.compareAndSet(true, false);
}
public void unlock() {
lock.set(true);
}
}</pre>
<p> </p>
<p>原理:CAS</p>
<p> </p>
<p>优点:</p>
<p> 速度快,约是ReentrantLock的2-3倍</p>
<p> </p>
<p> 缺点:</p>
<p> 需JDK5.0+</p>
<p> 无条件对象且不可重入</p>
<p> 未获取锁时直接调用unlock不抛IllegalMonitorStateException所以代码必须严格保证获取锁后才能调用unlock</p>
<p> </p>
<p>适用场景:</p>
<p> 不需要条件对象且当ReentrantLock的tryLock影响了你的性能的时候</p>
<p> </p>
<p>我的应用场景:</p>
<p> 最近项目中通信程序中的客户端的socket长连接的连接池,客户端使用连接具有高并发但占用连接时间非常短的特点,使用这个类代替ReentrantLock,性能提高了3倍左右</p>
</div>
<p> </p>
<p> </p>
<p>你这个有线程安全问题呢,怎么保证在tryLock 和unlock之间的线程安全(状态一直性)?</p>
<p> </p>
<p>ReentrantLock 是利用Thread 队列,只有独占线程看到共享资源,pack其他线程,待操作完毕,下一个线程unpack继续操作。同时还有JVM底层的操作。</p>
<p> </p>
<p> </p>
</div>
<p>如果任何线程使用都遵守tryLock返回true后再去unlock,不会有线程安全问题的,compareAndSet是个原子操作</p>
</div>
<p> </p>
<p> </p>
<p>我的天啊, 在同步(互斥)中间执行的代码叫做“临界区”,AtomicX类都是Nonblocking的,怎么取保其他线程不进入“临界区”,这个不算的话。线程安全,还应该保证 Thread的读和写的数据和主存中的一致。你这个类怎么取保?</p>
9 楼
asme2u
2010-09-24
hellojinjie 写道
asme2u 写道
ellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高
看来是ReentrantLock 里的tryLock太耗时了,才会使得用AtomicBoolean实现的Lock性能比ReentryLock好
正解,只有符合锁占用的时间与获取锁的时间可比拟时,这个类才有意义,所以我列出了适用场景。
8 楼
hellojinjie
2010-09-24
asme2u 写道
ellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高
看来是ReentrantLock 里的tryLock太耗时了,才会使得用AtomicBoolean实现的Lock性能比ReentryLock好
7 楼
asme2u
2010-09-24
<div class="quote_title">mercyblitz 写道</div>
<div class="quote_div">
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<pre name="code" class="java">import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author asme2u
*/
public class Lock {
private AtomicBoolean lock = new AtomicBoolean(true);
public boolean tryLock() {
return lock.compareAndSet(true, false);
}
public void unlock() {
lock.set(true);
}
}</pre>
<p> </p>
<p>原理:CAS</p>
<p> </p>
<p>优点:</p>
<p> 速度快,约是ReentrantLock的2-3倍</p>
<p> </p>
<p> 缺点:</p>
<p> 需JDK5.0+</p>
<p> 无条件对象且不可重入</p>
<p> 未获取锁时直接调用unlock不抛IllegalMonitorStateException所以代码必须严格保证获取锁后才能调用unlock</p>
<p> </p>
<p>适用场景:</p>
<p> 不需要条件对象且当ReentrantLock的tryLock影响了你的性能的时候</p>
<p> </p>
<p>我的应用场景:</p>
<p> 最近项目中通信程序中的客户端的socket长连接的连接池,客户端使用连接具有高并发但占用连接时间非常短的特点,使用这个类代替ReentrantLock,性能提高了3倍左右</p>
</div>
<p> </p>
<p> </p>
<p>你这个有线程安全问题呢,怎么保证在tryLock 和unlock之间的线程安全(状态一直性)?</p>
<p> </p>
<p>ReentrantLock 是利用Thread 队列,只有独占线程看到共享资源,pack其他线程,待操作完毕,下一个线程unpack继续操作。同时还有JVM底层的操作。</p>
<p> </p>
<p> </p>
</div>
<p>如果任何线程使用都遵守tryLock返回true后再去unlock,不会有线程安全问题的,compareAndSet是个原子操作</p>
<div class="quote_div">
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<pre name="code" class="java">import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author asme2u
*/
public class Lock {
private AtomicBoolean lock = new AtomicBoolean(true);
public boolean tryLock() {
return lock.compareAndSet(true, false);
}
public void unlock() {
lock.set(true);
}
}</pre>
<p> </p>
<p>原理:CAS</p>
<p> </p>
<p>优点:</p>
<p> 速度快,约是ReentrantLock的2-3倍</p>
<p> </p>
<p> 缺点:</p>
<p> 需JDK5.0+</p>
<p> 无条件对象且不可重入</p>
<p> 未获取锁时直接调用unlock不抛IllegalMonitorStateException所以代码必须严格保证获取锁后才能调用unlock</p>
<p> </p>
<p>适用场景:</p>
<p> 不需要条件对象且当ReentrantLock的tryLock影响了你的性能的时候</p>
<p> </p>
<p>我的应用场景:</p>
<p> 最近项目中通信程序中的客户端的socket长连接的连接池,客户端使用连接具有高并发但占用连接时间非常短的特点,使用这个类代替ReentrantLock,性能提高了3倍左右</p>
</div>
<p> </p>
<p> </p>
<p>你这个有线程安全问题呢,怎么保证在tryLock 和unlock之间的线程安全(状态一直性)?</p>
<p> </p>
<p>ReentrantLock 是利用Thread 队列,只有独占线程看到共享资源,pack其他线程,待操作完毕,下一个线程unpack继续操作。同时还有JVM底层的操作。</p>
<p> </p>
<p> </p>
</div>
<p>如果任何线程使用都遵守tryLock返回true后再去unlock,不会有线程安全问题的,compareAndSet是个原子操作</p>
6 楼
mercyblitz
2010-09-24
<div class="quote_title">asme2u 写道</div>
<div class="quote_div">
<pre name="code" class="java">import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author asme2u
*/
public class Lock {
private AtomicBoolean lock = new AtomicBoolean(true);
public boolean tryLock() {
return lock.compareAndSet(true, false);
}
public void unlock() {
lock.set(true);
}
}</pre>
<p> </p>
<p>原理:CAS</p>
<p> </p>
<p>优点:</p>
<p> 速度快,约是ReentrantLock的2-3倍</p>
<p> </p>
<p> 缺点:</p>
<p> 需JDK5.0+</p>
<p> 无条件对象且不可重入</p>
<p> 未获取锁时直接调用unlock不抛IllegalMonitorStateException所以代码必须严格保证获取锁后才能调用unlock</p>
<p> </p>
<p>适用场景:</p>
<p> 不需要条件对象且当ReentrantLock的tryLock影响了你的性能的时候</p>
<p> </p>
<p>我的应用场景:</p>
<p> 最近项目中通信程序中的客户端的socket长连接的连接池,客户端使用连接具有高并发但占用连接时间非常短的特点,使用这个类代替ReentrantLock,性能提高了3倍左右</p>
</div>
<p> </p>
<p> </p>
<p>你这个有线程安全问题呢,怎么保证在tryLock 和unlock之间的线程安全(状态一直性)?</p>
<p> </p>
<p>ReentrantLock 是利用Thread 队列,只有独占线程看到共享资源,pack其他线程,待操作完毕,下一个线程unpack继续操作。同时还有JVM底层的操作。</p>
<p> </p>
<p> </p>
<div class="quote_div">
<pre name="code" class="java">import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author asme2u
*/
public class Lock {
private AtomicBoolean lock = new AtomicBoolean(true);
public boolean tryLock() {
return lock.compareAndSet(true, false);
}
public void unlock() {
lock.set(true);
}
}</pre>
<p> </p>
<p>原理:CAS</p>
<p> </p>
<p>优点:</p>
<p> 速度快,约是ReentrantLock的2-3倍</p>
<p> </p>
<p> 缺点:</p>
<p> 需JDK5.0+</p>
<p> 无条件对象且不可重入</p>
<p> 未获取锁时直接调用unlock不抛IllegalMonitorStateException所以代码必须严格保证获取锁后才能调用unlock</p>
<p> </p>
<p>适用场景:</p>
<p> 不需要条件对象且当ReentrantLock的tryLock影响了你的性能的时候</p>
<p> </p>
<p>我的应用场景:</p>
<p> 最近项目中通信程序中的客户端的socket长连接的连接池,客户端使用连接具有高并发但占用连接时间非常短的特点,使用这个类代替ReentrantLock,性能提高了3倍左右</p>
</div>
<p> </p>
<p> </p>
<p>你这个有线程安全问题呢,怎么保证在tryLock 和unlock之间的线程安全(状态一直性)?</p>
<p> </p>
<p>ReentrantLock 是利用Thread 队列,只有独占线程看到共享资源,pack其他线程,待操作完毕,下一个线程unpack继续操作。同时还有JVM底层的操作。</p>
<p> </p>
<p> </p>
5 楼
asme2u
2010-09-24
<div class="quote_title">hellojinjie 写道</div>
<div class="quote_div">性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关??? <br><br>你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。</div>
<p>我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高</p>
<p> </p>
<div class="quote_div">性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关??? <br><br>你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。</div>
<p>我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高</p>
<p> </p>
4 楼
asme2u
2010-09-24
<div class="quote_title">hellojinjie 写道</div>
<div class="quote_div">很有创造力,可是 <br>>>> 速度快,约是ReentrantLock的2-3倍 <br>怎么得出来的呢?论据呢。。。。。</div>
<p> </p>
<p> </p>
<pre name="code" class="java">import java.util.concurrent.locks.ReentrantLock;
/**
* @author asme2u
*/
public class TestLock {
private static long c = 0;
public static void main(String[] args) {
final Lock l = new Lock();
// final ReentrantLock l = new ReentrantLock();
Thread t1 = new Thread() {
public void run() {
for (int i = 0; i < 100000000;) {
if (l.tryLock()) {
c++;
i++;
l.unlock();
}
}
}
};
Thread t2 = new Thread() {
public void run() {
for (int i = 0; i < 100000000;) {
if (l.tryLock()) {
c++;
i++;
l.unlock();
}
}
}
};
long t = System.currentTimeMillis();
Thread t3 = new Thread() {
public void run() {
for (int i = 0; i < 100000000;) {
if (l.tryLock()) {
c++;
i++;
l.unlock();
}
}
}
};
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException e) {
}
System.out.println(c);
System.out.println(System.currentTimeMillis() - t);
}
}
</pre>
<p> </p>
<p> </p>
<p>在我的破笔记本上,单核的,分别用连个锁,一个跑了35秒,一个跑了14秒</p>
<div class="quote_div">很有创造力,可是 <br>>>> 速度快,约是ReentrantLock的2-3倍 <br>怎么得出来的呢?论据呢。。。。。</div>
<p> </p>
<p> </p>
<pre name="code" class="java">import java.util.concurrent.locks.ReentrantLock;
/**
* @author asme2u
*/
public class TestLock {
private static long c = 0;
public static void main(String[] args) {
final Lock l = new Lock();
// final ReentrantLock l = new ReentrantLock();
Thread t1 = new Thread() {
public void run() {
for (int i = 0; i < 100000000;) {
if (l.tryLock()) {
c++;
i++;
l.unlock();
}
}
}
};
Thread t2 = new Thread() {
public void run() {
for (int i = 0; i < 100000000;) {
if (l.tryLock()) {
c++;
i++;
l.unlock();
}
}
}
};
long t = System.currentTimeMillis();
Thread t3 = new Thread() {
public void run() {
for (int i = 0; i < 100000000;) {
if (l.tryLock()) {
c++;
i++;
l.unlock();
}
}
}
};
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException e) {
}
System.out.println(c);
System.out.println(System.currentTimeMillis() - t);
}
}
</pre>
<p> </p>
<p> </p>
<p>在我的破笔记本上,单核的,分别用连个锁,一个跑了35秒,一个跑了14秒</p>
相关推荐
tryLock() 仅在调用时锁为空闲状态才获取该锁。如果锁可用,则获取锁,并立即返回值 true。如果锁不可用,则此方法将立即返回值 false。 lock 和 synchronized 都是锁的意思,但是它们有不同的实现机制和应用场景。...
public static boolean tryLock(String lockKey, int expireSeconds) { Jedis jedis = new Jedis("localhost", 6379); String result = jedis.set(lockKey, "locked", "NX", "EX", expireSeconds); jedis.close...
2. **定时等待**:通过`tryLock(long timeout, TimeUnit unit)`方法,线程可以设定一个等待时间去尝试获取锁,如果超时仍未获取到,线程将返回而不是继续等待。 3. **锁投票**:`ReentrantLock`的`tryLock()`方法...
这与`synchronized`块类似,但`ReentrantLock`提供了更细粒度的控制,如尝试非阻塞获取锁(`tryLock()`)、可中断的锁获取(`lockInterruptibly()`)以及对锁状态的查询方法。 总结来说,`ReentrantLock`是Java并发编程...
if (lock.tryLock(1000, TimeUnit.MILLISECONDS)) { // 尝试获取锁,超时时间为1秒 try { // 执行关键代码段 } finally { lock.unlock(); // 释放锁 } } else { System.out.println("Lock acquisition timed...
Java是一种广泛使用的面向对象的编程语言,以其跨平台性、高效性和安全性著称。"Java简单程序小例子"是学习Java编程的初级阶段常见的实践项目,通常包含一系列基础的代码示例,帮助初学者理解语言的基本语法和常用...
例如,`down_trylock()`和`up_read_trylock()`这样的宏可以帮助开发者在某些情况下避免等待锁。 #### 八、结语 《Linux内核同步操作详解》为开发者提供了丰富的理论知识和技术细节,帮助他们在开发驱动程序或其他...
- **Lock锁**:ReentrantLock是可重入锁,提供了比synchronized更细粒度的控制,如tryLock()、unlock()等。 3. **并发工具类** - **CountDownLatch**:用于计数,常用于多线程协同工作,当计数器归零时,所有等待...
其中,`lock`是最常用的一种,用于控制对共享资源的访问。 4. **线程池** 线程池是一种线程复用机制,它可以避免频繁创建和销毁线程的开销。C#的线程池由`ThreadPool`类提供。你可以通过`ThreadPool....
`lock`是C#中实现互斥访问的最简单方式。它基于`Monitor`类,确保同一时刻只有一个线程可以执行锁定的代码块: ```csharp object obj = new object(); lock (obj) { // 共享资源的代码 } ``` 这里,`obj`作为锁...
- **synchronized关键字**:这是最简单的锁实现方式,可以应用于方法或者代码块。 - **ReentrantLock类**:这是一个可重入的互斥锁,比synchronized更灵活,提供了一系列高级功能。 - **ReentrantReadWriteLock类**...
pthread_mutex_trylock用于尝试加锁,而不会阻塞。 2. 条件变量:条件变量是与互斥锁联合使用的同步机制,用于线程间的协调。条件变量允许线程因为某个条件未满足而处于阻塞状态,直到其他线程改变了这个条件并发送...
首先,我们来看最基本的同步机制——synchronized关键字。synchronized可以用于方法或者代码块,当它包裹的代码被执行时,会创建一个监视器锁,只有一个线程能获取这个锁并执行代码,其他线程必须等待锁的释放。例如...
这个简单的实现展示了如何在C++中创建自定义消息系统,包括定义消息结构、存储消息、发送和接收消息以及处理消息的逻辑。通过这种方式,你可以根据项目需求定制自己的通信协议,以实现更高效、更灵活的程序设计。...
- **解答**: 要实现线程之间的执行顺序,最简单的方法是使用`join()`方法。例如: ```java Thread t1 = new Thread(() -> { // T1 的任务 }); Thread t2 = new Thread(() -> { // T2 的任务 }); Thread t3 =...
- 可以通过tryLock尝试获取锁,增加灵活性。 - 提供更精细的锁释放控制,避免异常导致的死锁。 #### 5. 认识AQS - **AQS内部实现**: - 通过`state`字段记录锁的状态,使用CAS操作进行原子更新。 - 通过FIFO...
通常,使用阻塞队列是最简单且高效的解决方案,因为它已经内置了同步和等待机制。然而,在某些特定情况下,如需要更灵活的同步控制或者更高的性能,其他方法可能更合适。理解并熟练掌握这些机制对于进行高并发的Java...
- `lock`是C#中最简单的同步原语,它基于Monitor对象实现: ```csharp lock (obj) { // 访问共享资源的代码 } ``` 5. **线程池** - .NET框架中的线程池(ThreadPool)是一种高效的线程管理机制,它可以重用...
除了基本的线程创建和控制,Java还提供了丰富的同步机制,如`synchronized`关键字、`wait()`, `notify()`, `notifyAll()`方法,以及`Lock`接口(如`ReentrantLock`)和`Condition`接口,以支持更复杂的并发控制。...