锁定老帖子 主题:最简单高效的tryLock
精华帖 (0) :: 良好帖 (2) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-09-23
最后修改:2010-09-23
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倍左右 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-09-24
能说说怎么用嘛,写个简单例子
|
|
返回顶楼 | |
发表时间:2010-09-24
很有创造力,可是
>>> 速度快,约是ReentrantLock的2-3倍 怎么得出来的呢?论据呢。。。。。 |
|
返回顶楼 | |
发表时间:2010-09-24
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。 |
|
返回顶楼 | |
发表时间:2010-09-24
hellojinjie 写道
很有创造力,可是
>>> 速度快,约是ReentrantLock的2-3倍 怎么得出来的呢?论据呢。。。。。
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); } }
在我的破笔记本上,单核的,分别用连个锁,一个跑了35秒,一个跑了14秒 |
|
返回顶楼 | |
发表时间:2010-09-24
hellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。 我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高
|
|
返回顶楼 | |
发表时间:2010-09-24
asme2u 写道
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倍左右
你这个有线程安全问题呢,怎么保证在tryLock 和unlock之间的线程安全(状态一直性)?
ReentrantLock 是利用Thread 队列,只有独占线程看到共享资源,pack其他线程,待操作完毕,下一个线程unpack继续操作。同时还有JVM底层的操作。
|
|
返回顶楼 | |
发表时间:2010-09-24
mercyblitz 写道
asme2u 写道
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倍左右
你这个有线程安全问题呢,怎么保证在tryLock 和unlock之间的线程安全(状态一直性)?
ReentrantLock 是利用Thread 队列,只有独占线程看到共享资源,pack其他线程,待操作完毕,下一个线程unpack继续操作。同时还有JVM底层的操作。
如果任何线程使用都遵守tryLock返回true后再去unlock,不会有线程安全问题的,compareAndSet是个原子操作 |
|
返回顶楼 | |
发表时间:2010-09-24
最后修改:2010-09-24
asme2u 写道 ellojinjie 写道 性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。 我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高 看来是ReentrantLock 里的tryLock太耗时了,才会使得用AtomicBoolean实现的Lock性能比ReentryLock好 |
|
返回顶楼 | |
发表时间:2010-09-24
hellojinjie 写道 asme2u 写道 ellojinjie 写道 性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???
你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。 我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高 看来是ReentrantLock 里的tryLock太耗时了,才会使得用AtomicBoolean实现的Lock性能比ReentryLock好 正解,只有符合锁占用的时间与获取锁的时间可比拟时,这个类才有意义,所以我列出了适用场景。 |
|
返回顶楼 | |