黑马程序员_java5的Lock_21

来源:互联网 发布:杨辉三角形代码vb 编辑:程序博客网 时间:2024/06/06 02:43

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

一,Lock VS synchronized

Lock完全可以代替synchronized,那么是否应该抛弃掉synchronized呢?答案是否定的。

是否应该抛弃synchronized?

   在java5引进Lock后,实现了Lock接口的类就是ReentrantLock(呆会再解释Reentrant),因为java5之前synchronized的实现很烂,同样是为了实现互斥,ReentrantLock会比synchronized速度上快很多,不过到了jdk6之后就不是这样了,jdk5中,ReentrantLock快很多,但是到了jdk6,他们就没什么大的差别了。

synchronized的优点:锁的释放是语言内置的,不会出现忘记释放锁的情况,另外由于是语言内置的支持,调试是能很快知道锁被哪个线程持有,它加锁的次数。而Lock只是util.concurrent一个普通的类,所以调试器并不知道这个锁的任何信息,它只是一个普通的对象(当然你可以仔细观察每个线程的stack frame来看它在等待锁)。所以建议:如果只是为了实现互斥,那么使用synchronized(扔掉jdk5吧,现在都java7了),如果想用Lock附加的功能,那么才使用Lock。

二,Lock的具体使用

Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象。

读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!ReentrantReadWriteLock会使用两把锁来解决问题,一个读锁,一个写锁

线程进入读锁的前提条件:
    没有其他线程的写锁,
    没有写请求或者有写请求,但调用线程和持有锁的线程是同一个
线程进入写锁的前提条件:
    没有其他线程的读锁
    没有其他线程的写锁

总结这个锁机制的特性了: 
     (a).重入方面其内部的WriteLock可以获取ReadLock,但是反过来ReadLock想要获得WriteLock则永远都不要想。 

     (b).WriteLock可以降级为ReadLock,顺序是:先获得WriteLock再获得ReadLock,然后释放WriteLock,这时候线程将保持Readlock的持有。反过来ReadLock想要升级为WriteLock则不可能,为什么?参看(a),呵呵. 
     (c).ReadLock可以被多个线程持有并且在作用时排斥任何的WriteLock,而WriteLock则是完全的互斥。这一特性最为重要,因为对于高读取频率而相对较低写入的数据结构,使用此类锁同步机制则可以提高并发量。 
     (d).不管是ReadLock还是WriteLock都支持Interrupt,语义与ReentrantLock一致。 
     (e).WriteLock支持Condition并且与ReentrantLock语义一致,而ReadLock则不能使用Condition,否则抛出UnsupportedOperationException异常

三,结合java5的Lock技术实现一个简单的缓存器

-------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

详细请查看:<a href="http://www.itheima.com" target="blank">www.itheima.com</a>----


 

0 0
原创粉丝点击