Java的悲观锁与乐观锁
2015-11-04 13:10
204 查看
我们都知道,cpu是时分复用的,也就是把cpu的时间片,分配给不同的thread/process轮流执行,时间片与时间片之间,需要进行cpu切换,也就是会发生进程的切换。切换涉及到清空寄存器,缓存数据。然后重新加载新的thread所需数据。当一个线程被挂起时,加入到阻塞队列,在一定的时间或条件下,在通过notify(),notifyAll()唤醒回来。在某个资源不可用的时候,就将cpu让出,把当前等待线程切换为阻塞状态。等到资源(比如一个共享数据)可用了,那么就将线程唤醒,让他进入runnable状态等待cpu调度。这就是典型的悲观锁的实现。独占锁是一种悲观锁,synchronized就是一种独占锁,它假设最坏的情况,并且只有在确保其它线程不会造成干扰的情况下执行,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。
但是,由于在进程挂起和恢复执行过程中存在着很大的开销。当一个线程正在等待锁时,它不能做任何事,所以悲观锁有很大的缺点。举个例子,如果一个线程需要某个资源,但是这个资源的占用时间很短,当线程第一次抢占这个资源时,可能这个资源被占用,如果此时挂起这个线程,可能立刻就发现资源可用,然后又需要花费很长的时间重新抢占锁,时间代价就会非常的高。
所以就有了乐观锁的概念,他的核心思路就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。在上面的例子中,某个线程可以不让出cpu,而是一直while循环,如果失败就重试,直到成功为止。所以,当数据争用不严重时,乐观锁效果更好。比如CAS就是一种乐观锁思想的应用。
乐观锁又被称为锁的自旋
但是,由于在进程挂起和恢复执行过程中存在着很大的开销。当一个线程正在等待锁时,它不能做任何事,所以悲观锁有很大的缺点。举个例子,如果一个线程需要某个资源,但是这个资源的占用时间很短,当线程第一次抢占这个资源时,可能这个资源被占用,如果此时挂起这个线程,可能立刻就发现资源可用,然后又需要花费很长的时间重新抢占锁,时间代价就会非常的高。
所以就有了乐观锁的概念,他的核心思路就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。在上面的例子中,某个线程可以不让出cpu,而是一直while循环,如果失败就重试,直到成功为止。所以,当数据争用不严重时,乐观锁效果更好。比如CAS就是一种乐观锁思想的应用。
乐观锁又被称为锁的自旋
相关文章推荐
- Java反射机制
- 为什么选择 Java 8 ?
- Java单例中的延迟加载
- Java中的HashMap, Hashtable,TreeMap, LinkedHashMap
- 给Java开发者的Scala教程
- Java基础学习总结(24)——Java单元测试之JUnit4详解
- Java基础学习总结(24)——Java单元测试之JUnit4详解
- Java基础学习总结(24)——Java单元测试之JUnit4详解
- Java基础学习总结(24)——Java单元测试之JUnit4详解
- Java并发编程:线程池的使用
- SpringMVC简单介绍
- java实现斐波拉契数列
- 【Exception】java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;
- Spring整合JMS
- java中关于文本文件的读写方法实例总结
- javaWeb--API 自动化测试框架分享
- Java Main如何被执行?(转)
- eclipse不能写入classpath
- 给Java开发者的Scala教程
- 给Java开发者的Scala教程