在JDK1.5之前,也就是J.U.C加入JDK之前,Java是依靠synchronized关键字(JVM底层提供)来维护协调对共享字段的访问,保证对这些变量的独占访问权,并且以后其他线程忽的该锁时,将可以看到对这些变量进行的更改(可见性,互斥性)。

锁机制的问题:

  • 锁问题不可回避的,就是上下文切换,加重系统线程调度,引起性能问题;
  • 不一致的获得多个锁的顺序,还可能引发死锁;
  • 如果一个线程试图获得其他线程已经具有的锁时,那么该线程将被阻塞,直到该锁可用,期间它无法进行其他任何操作,试想对一组操作序列加锁,也许在这些操作序列中就仅仅一步操作需要同步,而其余大部分操作都可以同时进行,不会发生竞争问题。一个粗粒度的上锁策略,将严重的导致系统的吞吐量。
  • 如果阻塞的线程是优先级高的任务,那么可能造成非常不好的结果(线程的优先级倒置);

前篇中所涉及的关键字volatile,在此处也并不能胜任,因为它仅仅提供可见性原语,它并不提供互斥访问,原子操作原语(对volatile修饰的int递增操作)。独占锁是一种悲观锁,synchronized就是一种独占锁。

比较并交换(CAS)

支持并发的第一个处理器提供原子的测试并设置操作。现在的处理器(Inter和Sparc)使用的最通用的方法是实现名为比较并转换或者CAS的原语。

CAS操作包含三个操作数-内存位置(V),预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。CAS有效的说明了"我认为位置V应该包含值A;如果包含该值,则将B放在这个位置;否则,就不要更改该位置的值,只告诉我这个位置现在的值既可"。

lock-free , wait-free

如果每个线程在其线程任意延迟(或者甚至失败)时都将持续进行操作,就可以说该算法是wait-free的。与此形成对比的是,lock-free算法要求仅某个线程总是执行操作。(wait-free的另一种定义是保证每个线程在器有限的步骤中正确计算自己的操作,而不管其他线程的操作,计时,交叉,速度)

无阻塞算法被广泛的用在操作系统和JVM级别,进行诸如线程和进程的调度任务。虽然他们的实现比较复杂,但相对与锁定的备选算法,他们有许多优点:可以避免优先级倒置和死锁的发生,竞争比较便宜,协调发生在更细粒度级别,提高吞吐量,其定义:

                                                  一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法

上面说了一大堆CAS的好,最后也该客观的评价一下CAS,当然它也有其缺点:

  • "ABA"问题。J.U.C中AtomicMarkableReference, AtomicStampedReference解决"ABA"可以排上用场。
  • 不停的循环重试知道成功,消耗大量CPU资源。Exponential Backoff。
  • 在高度竞争的环境下,CAS性能反而比直接加锁低,所以CAS有他的适用场景。

J.U.C CAS的更多相关文章

  1. Problem J: Island Buses

    主要题意是:大海之间有岛,有的岛之间有桥,问你岛的个数,桥的个数,以及没有桥联通岛的个数,其中最后一次输入的没有回车,不注意的话最后一次会被吞,第二,桥的两端的标记是“X”(X也代表陆地),“X”的四 ...

  2. UVa11427 Expect the Expected

    数学期望 概率递推 每一天的概率都是独立且相同的.可以先推出每天打i盘赢j盘的概率f[i][j] f[i][j]=f[i-1][j]*(1-p) + f[i-1][j-1]*p 输 赢 设此人打一天胜 ...

  3. Tomcat崩溃

    参考: http://bbs.csdn.net/topics/390391810?page=1 自己遇到的: --------------------------------------------- ...

  4. Uva1624 Knots

    极其鬼畜的题. 初见根本没有思路. 二见根本没有思路. …… 多年(并不)之后突然想到,也许可以用链表模拟. 先用链表把每一个节点串起来,并对有覆盖的地方进行标记. 模拟解锁操作,如果一个节点和它所覆 ...

  5. Uva11464 Even Parity

    枚举每个格子的状态显然是不可能的. 思考发现,矩阵第一行的状态确定以后,下面的状态都可以递推出来. 于是状压枚举第一行的状态,递推全图的状态并判定是否可行. /*by SilverN*/ #inclu ...

  6. POJ1285 Combinations, Once Again(背包 排列组合)

    背包解组合数学问题,n种物品,每种num[i]个,求取r个的方法数. 背包思想,f[j]表示当前取j个数的方法数,则状态转移方程为 f[j] += f[k](max(j - num[i], 0) &l ...

  7. ZOJ 3703 Happy Programming Contest(DP)

    题目链接 输出路径,搞了一个DFS出来,主要是这里,浪费了好长时间. #include <cstdio> #include <string> #include <cstr ...

  8. HDU 4722 Good Numbers(DP)

    题目链接 脑子有点乱,有的地方写错了,尚大婶鄙视了... 来个模版的. #include <iostream> #include <cstdio> #include <c ...

  9. hdoj 4323

    题意:给你n个数,m个查询,查询中包括一个数和一个最大编辑距离d,问n个数中和这个数的编辑距离不超过d的有多少个 编辑距离:http://baike.baidu.com/view/2020247.ht ...

随机推荐

  1. MAC上安装mysql及workbench

    下载mysql for mac    https://dev.mysql.com/downloads/installer/ 官网下载很慢---百度云:链接: https://pan.baidu.com ...

  2. Spring入门之IOC

    IOC/DI: Spring最核心的灵魂,IOC/DI(控制反转/依赖注入)!,这里一定要理解他,理解这个思想.我会细说什么是IOC/DI.他的思想是什么.它带来了那些好处. 进入正题,先说说什么是i ...

  3. Pyqt4的对话框 -- 文件对话框

    文件对话框允许用户选择文件或文件夹,被选择的文件可进行读或写操作 # QInputDialog 文件对话框 # 本示例包含一个菜单栏,一个状态栏和一个被设置为中心部件的文本编辑器. # 状态栏的状态信 ...

  4. Mac安装Scala

    1. 下载,解压Scala sdk,2. 配置环境变量(.bash_profile) SCALA_HOME="/Users/soft/scala_soft/scala-2.11.6" ...

  5. Lambda表达式基础

    1.委托的典型用法 1.1定义一个委托: public delegate int AddDelegate(int i, int j); 1.2 定义一个MyClass类,放置一个满足 AddDeleg ...

  6. JAVA读取和写入properties文件

    1.读取 Properties prop = new Properties(); try { //这个getResourceAsStream方法就是把文件转为inputStream的方式 prop.l ...

  7. Ubuntu 设置内核版本的GRUB默认启动

    注:我只是一只小小的搬运工.这篇文章内容摘自: https://www.calazan.com/how-to-set-an-older-kernel-version-as-the-default-in ...

  8. 5大UX设计谬论,如何去补救?

     以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具. 每个新项目都是从学习开始的. 就像设计师需要了解一个特定的客户和他们的设计目标一样,客户需要了解设 ...

  9. swiper插件的简单使用,实现图片轮播

    移动端和p c端经常会遇到写轮播图的情况,这里只是简单的说一下swiper插件的简单用法(移动端为例). <!DOCTYPE html> <html lang="en&qu ...

  10. 使用jemeter手工编写注册、登陆脚本 运用 fiddler (三)

    手工注册脚本的录制 我们可以发现  编写手工脚本 需要用到两个软件一起合作才能编写成功 工作亦是如此  养成良好的团队合作精神 是必不可少的 现在我们来看手工编写注册脚本 第一步 :我们先进入网站首页 ...