文章转载自http://www.importnew.com/22078.html
悲观锁和乐观锁
我们都知道,CPU是时分复用的,就是CPU把时间片,分配给不同的thread/process轮流执行,时间片与时间片之间,需要进行CPU切换,也就是会发生进程的切换。切换涉及到清空寄存器、缓存数据。然后重新加载新的thread所需数据。当一个线程被挂起时,加入到阻塞队列,在一定的时间或条件下,通过notify(),notifyAll()唤醒回来。在某个资源不可用的时候,就把CPU让出去,把当前的线程切换到阻塞状态。等到资源(如一个共享数据)可用了,就将线程唤醒,让他进入runnable状态等待CPU调度。这就是典型的悲观锁实现。独占锁是一种悲观锁,synchronized就是一种独占锁,他假设最坏的情况,并且只有在确保其他线程不会造成干扰的情况下执行,会导致其他所有需要锁的线程挂起,等待持有锁的线程释放锁。
但是,由于在进程挂起和恢复执行过程中存在着很大额开销。当一个线程正在等待锁时,他不能做任何事情,所有悲观锁有很大的缺点。举个例子,如果线程需要某个资源,但是资源的占用时间很短,当线程第一次抢占这个资源时,可能这个资源被占用,如果此时挂起这个线程,可能立刻就发现资源可用,然后有需要花费很长的时间重新抢占锁,时间代价就会非常的高。
所以就有的乐观锁的概念,他的核心思路就是:每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,知道成功为止。在上面的例子中,某个线程可以不让出CPU,而是一直WHILE循环,如果失败就重试,直到成功为止。所以,当数据争用不严重的时,乐观锁效果更好,比如CAS就是一种乐观锁思想的应用。
Java中CAS的实现
CAS就是Compare and Swap的意思,比较并操作。很多的CPU直接支持CAS指令。CAS是项乐观锁技术,当多个线程尝试使用CAS同时更新一个变量时,只有其中一个线程能够更新变量的值,而其他线程都失败,失败的线程不会被挂起,而是被告知此次竞争失败,并可以再次尝试。CAS有3个操作数,内存值V,就的预期值A,要修改的新值B。当且仅当预期值A与内存值V相同时,将内存值修改为B,否则什么都不做。
JDK1.5中引人了底层的支持,在INT、long和对象的引用等类型上都公开的CAS操作,并且JVM把他们编译为底层硬件提供的最有效的方法,在运行CAS的平台上,运行时把他们编译为相应的机器指令。在java.util.concurrent.atmoic包下面所有的原子变量类型中,比如AtomicInteger,都使用了这些底层的JVM支持为数字类型的引用提供了一种高效的CAS操作。
在CAS操作中会出现ABA问题。就是如果V值现有A变B,再由B变A,那么仍然认为是发生了变化,并且需要重新执行算法中的步骤。有个简单的解决方案:不是更新某个引用的值,而是更新两个值,包括一个引用和一个版本号,即使这个值由A变B,然后变为A,版本号也是不同的。AtomicStampedReference和AtomicMarkableReference支持在两个变量上执行原子的条件更新。AtomicStampedReference更新一个“对象-引用”二元组,通过在引用上加上“版本号”,从而避免“ABA”问题,AtomicMarkableReference将更新一个“对象引用-布尔值”的二元组。
AtomicInteger的实现
AtomicInteger是一个支持原子操作的Integer类,就是保证AtomicInteger类型变量的增加和减少操作是原子性的,不会出现多个线程下数据不一致的问题。如果不使用AtomicInteger,要实现一个按顺序获取的ID,就必须在每次获取时进行加锁操作,以避免出现并发时获取到同样ID的现象。
编程语言java-并发(锁)的更多相关文章
-
Java 并发锁
Java 中的锁 阻塞锁.可重入锁.读写锁.互斥锁.悲观锁.乐观锁.公平锁.偏向锁.对象锁.线程锁.锁粗化.锁消除.轻量级锁.重量级锁.信号量.独享锁.共享锁.分段锁 一.常见的锁 synchroni ...
-
java并发锁ReentrantReadWriteLock读写锁源码分析
1.ReentrantReadWriterLock 基础 所谓读写锁,是对访问资源共享锁和排斥锁,一般的重入性语义为如果对资源加了写锁,其他线程无法再获得写锁与读锁,但是持有写锁的线程,可以对资源加读 ...
- 深入理解 Java 并发锁
-
百万并发中间件系统的内核设计看Java并发性能优化
“ 这篇文章,给大家聊聊一个百万级并发的中间件系统的内核代码里的锁性能优化. 很多同学都对Java并发编程很感兴趣,学习了很多相关的技术和知识.比如volatile.Atomic.synchroniz ...
-
深入并发锁,解析Synchronized锁升级
这篇文章分为六个部分,不同特性的锁分类,并发锁的不同设计,Synchronized中的锁升级,ReentrantLock和ReadWriteLock的应用,帮助你梳理 Java 并发锁及相关的操作. ...
-
Java 并发机制底层实现 —— volatile 原理、synchronize 锁优化机制
本书部分摘自<Java 并发编程的艺术> 概述 相信大家都很熟悉如何使用 Java 编写处理并发的代码,也知道 Java 代码在编译后变成 Class 字节码,字节码被类加载器加载到 JV ...
-
【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
-
【Java并发编程实战】-----&ldquo;J.U.C&rdquo;:CLH队列锁
在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...
-
【Java并发系列04】线程锁synchronized和Lock和volatile和Condition
img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比 ...
-
【Java并发编程实战】-----&ldquo;J.U.C&rdquo;:锁,lock
在java中有两种方法实现锁机制,一种是在前一篇博客中([java7并发编程实战]-----线程同步机制:synchronized)介绍的synchronized,而另一种是比synchronized ...
随机推荐
-
web性能优化
常用方法 压缩源码和图片 JavaScript文件源代码:可以采用混淆压缩的方式,CSS文件源代码进行普通压缩,JPG图片可以根据具体质量来压缩为50%到70%,PNG可 以使用一些开源压缩软件来压缩 ...
-
Lind.DDD.Events事件总线~自动化注册
回到目录 让大叔兴奋的自动化注册 对于领域事件之前说过,在程序启动时订阅(注册)一些事件处理程序,然后在程序的具体位置去发布(触发)它,这是传统的pub/sub模式的体现,当然也没有什么问题,为了让它 ...
-
Swift +AFNetworking3.0 Get
let manager = AFHTTPSessionManager() let url = "http://v.juhe.cn/weather/index" let ," ...
-
Mysql 中 text类型和 blog类型的异同
MySQL存在text和blob: (1)相同 在TEXT或BLOB列的存储或检索过程中,不存在大小写转换,当未运行在严格模式时,如果你为BLOB或TEXT列分配一个超过该列类型的最大长度的值值,值被 ...
-
mysql问题Connection using old (pre-4.1.1) authentication protocol refused (client option &#39;secure_auth&#39; enabled)的解决方法
在mysql命令行界面输入 mysql> set old_passwords=0;mysql> SET PASSWORD FOR hhds_test=PASSWORD('hhds_test ...
-
[转]用Node.js创建自签名的HTTPS服务器
用Node.js创建自签名的HTTPS服务器 创建自己的CA机构 创建服务器端证书 创建客户端证书 将证书打包 创建自己的CA机构 为CA生成私钥 openssl genrsa -out ca-key ...
-
SQL Server 无法打开物理文件的 2 种解决办法
解决方法: 方法1.无法打开可以能是没有权限.如果是这样以管理员身份运行Managerment Studio就可以了. 方法2.找到指定的数据库文件.右键属性-->安全-->勾上 ‘完全 ...
-
C语言语法
1.函数指针类型定义,然后指针结构体类型定义,最后的调用形式为aaa.bbb();(aaa为结构体变量)或者 aaa->bbb();(aaa为结构体指针),函数指针最好用结构体封装起来变成指针结 ...
-
错误 在类中找不到main方法请将main方法定义为 public static void main String args否则JavaFX应用程序类必须扩展javafx-ap
最近在使用eclipse编写java程序时遇到这样一个问题: 错误在类中找不到main方法,请将main方法定义为 public static void main(String[] args)否则 J ...
-
float清除浮动
清除浮动: 在非IE浏览器下,当容器的高度为auto,且容器的内容中有浮动(float为left或right)的元素,在这种情况下,容器的高度不能自动伸长以适应内容的高度,使得内容溢出到容器外面而影响 ...