cas 订阅
中国科学院(英文名称:Chinese Academy of Sciences,简称中科院)成立于1949年11月,为中国自然科学最高学术机构、科学技术最高咨询机构、自然科学与高技术综合研究发展中心。中国科学院提出了建设国家创新体系的构想,先后实施知识创新工程、“创新2020”、《“率先行动”计划暨全面深化改革纲要》,提出了《迎接知识经济时代,建设国家创新体系》、《创新促进发展,科技引领未来》、《创新2050:科学技术与中国的未来》、《科技发展新态势与面向2020年的战略选择》等战略研究报告。据2018年11月中国科学院官网显示,全院共拥有12个分院、100多家科研院所、3所大学(中国科学院大学、中国科学技术大学,与上海市共建上海科技大学)、130多个国家级重点实验室和工程中心、210多个野外观测台站,承担20余项国家重大科技基础设施的建设与运行,正式职工7.1万余人,在学研究生6.4万余人;建成了完整的自然科学学科体系,物理、化学、材料科学、数学、环境与生态学、地球科学等学科整体水平已进入世界先进行列,一些领域方向也具备了进入世界第一方阵的良好态势。在解决关系国家全局和长远发展的重大问题上,已成为不可替代的国家战略科技力量。一批科学家在国家重大科技任务中发挥了关键和中坚作用,并作为我国科技界的代表活跃在国际科技前沿。 [1]  2019年9月,经党中央批准,十九届中央第四轮巡视将对中国科学院党组织开展常规巡视。 [2] 展开全文
中国科学院(英文名称:Chinese Academy of Sciences,简称中科院)成立于1949年11月,为中国自然科学最高学术机构、科学技术最高咨询机构、自然科学与高技术综合研究发展中心。中国科学院提出了建设国家创新体系的构想,先后实施知识创新工程、“创新2020”、《“率先行动”计划暨全面深化改革纲要》,提出了《迎接知识经济时代,建设国家创新体系》、《创新促进发展,科技引领未来》、《创新2050:科学技术与中国的未来》、《科技发展新态势与面向2020年的战略选择》等战略研究报告。据2018年11月中国科学院官网显示,全院共拥有12个分院、100多家科研院所、3所大学(中国科学院大学、中国科学技术大学,与上海市共建上海科技大学)、130多个国家级重点实验室和工程中心、210多个野外观测台站,承担20余项国家重大科技基础设施的建设与运行,正式职工7.1万余人,在学研究生6.4万余人;建成了完整的自然科学学科体系,物理、化学、材料科学、数学、环境与生态学、地球科学等学科整体水平已进入世界先进行列,一些领域方向也具备了进入世界第一方阵的良好态势。在解决关系国家全局和长远发展的重大问题上,已成为不可替代的国家战略科技力量。一批科学家在国家重大科技任务中发挥了关键和中坚作用,并作为我国科技界的代表活跃在国际科技前沿。 [1]  2019年9月,经党中央批准,十九届中央第四轮巡视将对中国科学院党组织开展常规巡视。 [2]
信息
主管部门
中华人民共和国国务院
拉丁文名
Academia Sinica
下辖分院
12个 [1]
现任院长
白春礼
机构简称
中科院·CAS
中文名
中国科学院
性    质
国务院直属事业单位
成立时间
1949年11月
机构地址
北京市三里河路52号
外文名
Chinese Academy of Sciences
中国科学院中科院史
1949年3月下旬,中共中央进驻北平,开始酝酿中国科学院,由郭沫若负责。1949年6月,中共中央决定由陆定一负责筹备建立科学院,恽子强和丁瓒协助,钱三强和黄宗甄参与。1949年9月,钱三强和丁瓒共同起草《建立人民科学院草案》,确定中科院基本框架。1949年9月27日,中国科学院成立,为政务院下设单位,行使管理全国科学研究事业的政府行政职能。1949年10月19日,中央人民政府委员会命郭沫若为第一任中科院院长,陈伯达、李四光、陶孟和、竺可桢为第一任中科院副院长。1949年11月1日,中科院在北京开始办公,并将11月1日定为中国科学院成立日。1949年11月5日,中科院接收国立北平研究院总办事处及所属的原子学、物理学、化学、植物学、动物学和史学6个研究,以及原中央研究院历史语言研究所在北京的图书史料整理处所。 [3]  1949年11月23日,中科院院址迁入北京王府大街9号;1950年6月23日,中科院院址迁至北京文津街3号静生生物调查所原址;1966年,中科院院址迁往北京西郊友谊宾馆北馆;1970年7月,中科院院址迁往北京三里河路52号原国家科委旧址。1949年12月16日,中科院接收静生生物调查所,成立静生生物调查所整理委员会。1949年12月21日,中科院接收西北科学考察团。1950年3月,经政务院批准,中国科学院华东办事处在上海成立;1955年2月更名为中国科学院上海办事处;1958年11月,正式成立中国科学院上海分院。1950年3月21日,中科院接收中央研究院在上海的化学、植物、动物和工学四个研究所,医学和药学两个研究所筹备处,接收北平研究院在上海的生理学、药物两个研究所和物理学研究所的结晶学研究室。 1950年4月6日,在中科院接收中央研究院办事处和社会、物理、气象、天文、地质5个研究所以及中国地理研究所。至此,中科院对原中研和北研的直属研究所接收完毕。1950年5月,首批15个研究机构及3个研究机构筹备处成立。中科院接收华北大学研究部历史研究室。1950年11月,中科院地质研究所和古生物研究所被中国地质工作计划指导委员会接收;1955年1月,中科院将此两研究所收回。1950年9月-1951年2月,中科院先后接收云南农林植物调查所、北研植物学所云南工作站、庐山森林植物园、中国西北植物调查所、国民党政府国史馆、中国海洋研究所。与中央军委气象局共同接收徐家汇观象台、佘山观象台。1950年,研究机构改组,把原有研究机构,合并改组为17个研究所、台、馆,1个委员会,另设3个研究所筹备处。1950年,中科院开始统一与审订自然科学名词;1955年11月15日,学术名词统一工作委员会划归中科院领导。1951年2月3日,中国科学院图书馆成立。1951年6月,中国科学院与教育部联合发布《1951年暑期招收研究实习员、研究生办法》,成为新中国开始研究生培养的标志。 [4]  1952年8月28日,中国科学院东北分院(现中国科学院沈阳分院、长春分院)成立。 [5]  1954年3月,中央确立建设以中国科学院为中心的国家科技体系。1954年9月21日,全国人大第一次会议通过《中华人民共和国国务院组织法》,不再把科学院列为政府部门。1954年11月10日,国务院发出《关于设立、调整中央和地方国家行政机关及其有关事项的通知》,宣布中科院不再作为国务院的组成部分,但工作仍受国务院指导。1955年5月12日,中国科学院研究生招生委员会成立。1955年6月,中国科学院学部成立。首批选聘233位学部委员。1955年8月,周恩来签发颁布《中国科学院研究生暂行条例》。1955年9月26日,中科院石油研究所学术委员会成立,各中科院下属研究所开始建立各自的学术委员会。 [6]  1956年1月1日中科院院部机构调整:(1)原“办公厅学术行政工作”与原秘书处合并成学术秘书处,原办公厅撤销。(2)成立管理局。(3)成立联络局。(4)成立科学干部培养部。(5)原人事局改称干部局。(6)撤销原编译局,将其部分工作并入科学出版社。(7)成立综合考察委员会。(8)原四个学部名称及职责均不变。1956年7月,成立计算技术所等三个研究所筹委会,并建立半导体物理研究小组。 1957年1月1日,中科院机关调整:(1)撤消学术秘书处。(2)恢复办公厅、计划局,设立宣传局和器材局。(3)干部培养部改为干部培养局。1957年,中科院党组成立“哲学社会科学部分党组”。1958年,中国科学院创办长春光学精密机械学院(现长春理工大学),1971年该校划归第五机械工业部领导。 [7-8]  1958年7月,中国科学院原子核科学委员会成立。1958年9月20日,中国科学院所属的中国科学技术大学在北京成立,中科院对中国科大实施“全院办校,所系结合”的办学方针。 [9]  1958年9月13日,中科院党组成立中国科学院党组新技术办公室。1960年1月,中科院获准建设四个配备全套设备的工厂。1960年7月2日,中国科学院新技术局成立。1960年9月,由中国科学院兰州分院开办的甘肃科学技术大学正式开学,1961年8月合并到兰州大学。 [10]  1961年6月至1962年底,进行大规模精简,撤销除新疆分院外的各省级分院和大批研究所,成立5个大区分院和华北办事处。1961年7月,“科学十四条”经中央批准正式以中央文件下发执行。1964年9月,中国科学院在北京中关村试办“中国科学院研究生院”;1966年“文革”开始后,研究生院停办。1964年10月16日,中国自行研制的第一颗原子弹爆炸成功,中国科学院为此做了大量关键性的工作。1964年12月,赵九章致函周恩来。不久,人造卫星研制工作重新上马。1965年9月,上海生物化学所、上海有机化学所与北京大学化学系合作,在世界上第一次用人工方法合成了具有较高生物活性的牛胰岛素结晶。 1967年6月,中国成功爆炸第一颗氢弹,中国科学院对此做出了重大贡献。1967年7月30日,中国科学院革命委员会成立。1967年11月28日,中国科学院地震办公室成立。1968年至1972年,中科院大批院属机构被划归国防部门,或下放地方,或撤销。1970年4月,以中科院为主研制的中国第一颗人造地球卫星成功发射。1970年7月1日,国家科委与中科院合并,成立新的中国科学院革命委员会。 1973年,国务院科教组的科技组并入中国科学院。1975年6月20日,中科院将1968年交给国防部门三十个科研事业单位中的六个从国防部门划回。1975年7月-11月,胡耀邦等整顿中科院。1977年5月,哲学社会科学部改称中国社会科学院。1977年8月,中国科学院和教育部受邓小平委托召开科教工作座谈会。1977年9月18日起,中科院不再承担原国家科委的职能。1978年3月,全国科学大会在北京召开,中国科学院承担了大会筹备的大量工作。1978年3月1日,经党中央国务院批准创办的新中国第一个研究生院——中国科学技术大学研究生院在北京成立;1982年5月,中科院党组批准同时使用校名中国科学院研究生院、中国科学技术大学研究生院(北京);2000年12月正式更名为中国科学院研究生院;2012年6月27日更名为中国科学院大学。 [11]  1978年4月,开始大规模收回和新建研究所,重建分院。同年,中国科学院在原有1所中国科技大学基础上,接收黑龙江工学院(更名为哈尔滨科学技术大学)、浙江大学、成都工学院(更名为成都科学技术大学)3所大学。从1981年起,浙江大学、成都科技大学、哈尔滨科技大学不再属科学院领导。 [12-13]  1979年1月,中国科学院学部恢复活动。次年10月,增补283位学部委员。 1981年3月6日,中央首次明确中科院办院方针。1981年5月11-20日,第四次学部委员大会召开,推选卢嘉锡任院长。1982年3月,设立面向全国的中国科学院科学基金。1984年1月,中央宣布中国科学院实行院长负责制。中科院试行博士后制度。8月8日,建立研究所开放日制度,每年在建院周年日(11月1日)前后开放一次,每次开放3天左右。1985年4月1日,全面实行所长负责制。1985年7月1日,中国科学院在全国率先建立了开放实验室,首批开放2个研究所和17个实验室。 [14]  1986年3月3日,王大珩等4位学部委员提出“关于跟踪研究外国战略高技术的建议”。“863计划“随即启动。 1987年2月,周光召院长提出新的办院方针,其后又提出实行“一院两种运行机制”。1991年,中国科学院增选210名学部委员,确定了规范化的增选制度。1993年10月,国务院批准“中国科学院学部委员”改称“中国科学院院士”。1994年1月22日,推出吸引优秀中青年科技人才的“百人计划”。1995年8月30日,中国科学院与上海市人民政府签定全面科技合作协议。在此前后,科学院在本年内还与新疆维吾尔自治区、浙江省、云南省签订了科技合作协议书。 [15-16]  1996年6月,中国科学院国家基因研究中心于在世界上首次成功构建了高分辨率的水稻基因组物理图。8月,由近代物理所和高能所合作,在世界上首次合成并鉴别出新核素镅-235。 [17]  1998年2月4日,江泽民总书记批示支持中国科学院先行进行国家创新体系试点。7月9日,知识创新工程正式启动。1999年,联合有关部门启动建设中国高速互联网络示范工程(CNCnet)骨干网。1999年,中国科学院决定在全国20所高校设立"中国科学院奖学金"。 [18]  1999年,中科院与甘肃省签订战略合作协议。 [19]  2001年,自1992年起,空间科学与应用研究中心等35个单位参与了“神舟”飞船应用系统的研究工作。 2002年1月,路甬祥院长提出新时期办院方针。2004年3月12日,中科院与黑龙江省签署全面科技合作协议。 [20]  2004年4月14日,中科院与云南省签署全面科技合作协议。 [21]  2005年3月1日,中国科学院北京分院成立。 [22]  2005年7月6日,中科院和天津市签署全面科技合作协议。 [23]  2006年3月,颁布《中国科学院章程》。2007年3月16日,中科院与新疆签署科技合作协议书。 [24]  2000年7月,中科院与山西省签订长期合作协议。 [25]  2008年9月26日,中国科学院与上海市人民政府签订《进一步深化院市合作协议书》,中国科学院上海浦东科技园同时揭牌。 [26]  2009年1月21日,中国科学院知识产权网建成开通。 [27]  2009年1月22日,中科院与广东省签署全面战略合作协议。 [28]  2009年3月3日,中科院与青岛市签署全面战略合作协议。 [29]  2009年3月6日,中国科学院与山东省人民政府在北京签署全面战略合作协议。 [30]  2009年3月10日,中科院与甘肃省在京签署《全面战略科技合作协议》。 [31]  2009年3月13日,中科院与西藏自治区、浙江省在京分别签署《科技合作协议书》、《院市全面科技合作协议》。 [32]  2009年6月10日,《创新2050:科学技术与中国的未来》系列研究报告发布。2010年3月12日,中科院与贵州省签署全面战略合作协议。 [33]  2010年3月31日,国务院决定中国科学院实施“创新2020”,创新2020随即启动。2011年3月,白春礼院长提出“民主办院、开放兴院、人才强院”发展战略。2011年3月10日,中科院与辽宁省签署全面科技合作协议。 [34]  2011年10月31日,中科院与河北省签署全面战略科技合作协议。 [35]  2012年3月,中科院分别与江西省、甘肃省在北京签署《江西省人民政府与中国科学院共建江西省科学院协议》、《共同支持甘肃省科学院发展协议》。 [36-37]  2012年11月25日,中国科学院与广西壮族自治区人民政府签署科技合作协议和共同支持广西科学院建设和发展协议。 [38]  2013年1月28日,中国科学院与中国工程物理研究院签署战略合作框架协议。 [39]  2013年7月17日,习近平总书记考察中科院,提出“四个率先”。 [6]  2013年9月30日,中国科学院与上海市共建的上海科技大学正式建立。 [40]  2015年7月28日,中科院与上海市签署全面深化合作协议。 [41]  2016年8月16日,中国科学院与河南省人民政府在京签署科技合作协议。 [42]  2016年9月21日,中科院与四川省签署第四轮全面科技合作协议。 [43]  2016年11月19日,中国科学院与深圳市人民政府签署在深合作办学备忘录,双方将依托中国科学院深圳先进技术研究院合作建设中国科学院大学深圳校区。 [44]  2016年12月8日,中国科学院与广东省人民政府签署“十三五”全面战略合作协议。 [45]  2017年1月,中国科学院与江西省人民政府签署全面战略合作协议。 [46]  2017年11月10日,中科院与国家海洋局签署战略合作框架协议。 [47]  2017年11月22日,中科院与吉林省签署科技创新合作协议。 [48]  2017年12月3日,中科院与深圳市签署合作协议,共建深圳国际科技产业创新中心。 [49]  2017年12月20日,中科院与福建省政府、福州市政府在福州签署共建中国科学院大学福建学院协议。 [50]  2018年2月6日,中科院与陕西省签署共建西安科学园协议。 [51]  2018年3月22日,中科院与军事科学院签署战略合作框架协议。 [52]  2018年4月4日,中国科学院与重庆市人民政府在重庆签署共建新型科教创产融合发展联合体战略合作协议,双方携手共建中国科学院大学重庆学院。 [53]  2018年11月4日,中科院倡议并联合40多个国家、地区的科教机构和相关国际组织发起成立了“一带一路”国际科学组织联盟(ANSO)。 [54]  2018年11月8日,中国科学院与香港特区政府在港签署《关于中国科学院在香港设立院属机构的备忘录》,推动中科院在港的研发工作。 [55]  2018年11月16日,中国科学院与深圳市人民政府签署协议书,合作共建中国科学院深圳理工大学。 [56]  2018年11月18日,中科院与广东省签署共同推进粤港澳大湾区国际科技创新中心建设合作协议。 [57]  2018年11月21日,中国科学院分别与内蒙古自治区、中国铁路总公司签署全面科技合作协议、战略合作协议。 [58-59]  2019年1月31日,中国科学院与中国核工业集团有限公司签署全面战略合作协议。 [60]  2020年5月13日,作为第一批倡议方,与国家发展改革委等发起“数字化转型伙伴行动”倡议。 [61] 
收起全文
精华内容
下载资源
问答
  • CAS

    千次阅读 多人点赞 2019-08-21 00:56:30
    CAS 原理: CAS(Compare and Swap)有三个参数,内存值V、旧的预期值A、即将更新的值B,当且仅当预期值 A 和内存值 V 相同时,将内存值修改为B并返回true,否则什么都不做,并返回false。 java 中的应用 java.util...

    CAS 原理:

    CAS(Compare and Swap)有三个参数,内存值V、旧的预期值A、即将更新的值B,当且仅当预期值 A 和内存值 V 相同时,将内存值修改为B并返回true,否则什么都不做,并返回false。

    java 中的应用

    1. java.util.concurrent(J.U.C) 中提供的 atomic 包中的类,使用的是乐观锁,用到的机制就是CAS,当多个线程尝试使用 CAS 同时更新一个变量时,只有其中一个线程可能更新变量的值,而其他线程都失败,失败的线程不会被挂起,而是被告知这次竞争失败,并可以再次尝试。
    2. 以 AtomicInteger 为例,研究在没有锁的情况下是如何做到数据正确性的。
    public class AtomicInteger extends Number implements java.io.Serializable {
        // setup to use Unsafe.compareAndSwapInt for updates
        private static final Unsafe unsafe = Unsafe.getUnsafe();
        private static final long valueOffset;
    
        static {
            try {
                valueOffset = unsafe.objectFieldOffset
                    (AtomicInteger.class.getDeclaredField("value"));
            } catch (Exception ex) { throw new Error(ex); }
        }
    
        private volatile int value;
        public final int get() {return value;}
    }
    

    例如 AtomicInteger 中有一个原子方式 i++ 操作,即

    1. 调用 incrementAndGet(),而 incrementAndGet() 调用 unsafe下的方法 getAndAddInt()
    public final int incrementAndGet() {
            return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
        }
        
     public final int getAndAddInt(Object var1, long var2, int var4) {
            int var5;
            do {
                var5 = this.getIntVolatile(var1, var2);
            } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
    
            return var5;
        }
        
         public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
    
    1. getAndAddInt() 中有一个 valueOffset 参数,这个值是 value 值在 AtomicInteger 类型中内存的偏移地址。传入的 valueOffset 参数会在后续方法中,直接从内存位置读取这个字段的值。
    2. 得到最新值后,调用 compareAndSwapInt 来更新最新值,如果对象中 offset 偏移位置的值等于期望值(expected),就将该 offset 处的值更新为 x,当更新成功时,返回 true。结合前面调用来看,如果当前值是 v,就设置为 v+1。否则重试直到成功为止。
      不仅仅是 AtomicInteger 用到了 CAS,整个 java.util.concurrent 中所有无阻塞共享内存和锁的实现都是基于 CAS 实现的。

    CAS 缺点

    1. ABA问题。
      因为 CAS 需要在操作值的时候检查下值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么使用 CAS 进行检查时会发现它的值没有发生变化,但是实际上却变化了。
      ABA问题的解决思路就是使用版本号。在变量前面追加上版本号,每次变量更新的时候把版本号加一,那么A-B-A 就会变成1A-2B-3A。
      从Java1.5开始JDK的atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。
    2. 循环时间长开销大。
      自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。如果JVM能支持处理器提供的pause指令那么效率会有一定的提升,pause指令有两个作用,第一它可以延迟流水线执行指令(de-pipeline),使CPU不会消耗过多的执行资源,延迟的时间取决于具体实现的版本,在一些处理器上延迟时间是零。第二它可以避免在退出循环的时候因内存顺序冲突(memory order violation)而引起CPU流水线被清空(CPU pipeline flush),从而提高CPU的执行效率。
    3. 只能保证一个共享变量的原子操作。
      当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁,或者有一个取巧的办法,就是把多个共享变量合并成一个共享变量来操作。比如有两个共享变量i=2,j=a,合并一下ij=2a,然后用CAS来操作ij。从Java1.5开始JDK提供了AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行CAS操作。

    atomic原子类

    1. 原子类由 CAS 操作保证原子性,由 volatile 关键字保证可见性。
    2. 可以粗略分成五类:
    1. 整型、长整型、布尔型、引用类型的原子类
      AtomicInteger、AtomicLong、AtomicBoolean、AtomicReference
    2. 整型数组、长整型数组、引用数组的原子类
      AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray
    3. 整型字段、长整型字段、引用字段更新的原子类
      AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater
    4. 解决ABA问题的原子类
      AtomicMarkableReference、AtomicStampedReference
    5. jdk 1.8新增的更高性能的原子累加器
      LongAdder、DoubleAdder、LongAccumulator、DoubleAccumulator
    1. 原子类的底层操作都是通过 Unsafe 类完成,每个原子类内部都有一个 Unsafe 类的静态引用。Unsafe 类中大部分都是native方法。

    private static final Unsafe unsafe = Unsafe.getUnsafe();

    1. AtomicInteger 内部由一个 int 域来保存值,其由volatile关键字修饰,用于保证可见性。类似的,AtomicLong内部是一个long型的value,AtomicBoolean 内部也是一个int,但其只会取值0或1。

    private volatile int value;

    1. AtomicInteger中有一个 compareAndSet 方法,通过 CAS 对变量进行原子更新。它通过调用 Unsafe 的 native函数实现:unsafe.compareAndSwapInt(this, valueOffset, expect, update)。
    展开全文
  • cas

    千次阅读 2014-06-30 23:52:04
    cas
    cas?
    展开全文
  • 面试必问的CAS,你懂了吗?

    万次阅读 多人点赞 2018-03-14 22:29:19
    面试必问的CAS,你懂了吗?

    目录

    概述

    案例

    CAS是什么?

    源码分析

    intel手册对lock前缀的说明如下:

    CAS的缺点:

    循环时间长开销很大:

    只能保证一个变量的原子操作:

    什么是ABA问题?ABA问题怎么解决?


    概述

    CAS(Compare-and-Swap),即比较并替换,是一种实现并发算法时常用到的技术,Java并发包中的很多类都使用了CAS技术。CAS也是现在面试经常问的问题,本文将深入的介绍CAS的原理。

     

    案例

    介绍CAS之前,我们先来看一个例子。

    /**
     * @author joonwhee
     * @date 2019/7/6
     */
    public class VolatileTest {
        
        public static volatile int race = 0;
    
        private static final int THREADS_COUNT = 20;
        
        public static void increase() {
            race++;
        }
    
        public static void main(String[] args) throws InterruptedException {
            Thread[] threads = new Thread[THREADS_COUNT];
            for (int i = 0; i < THREADS_COUNT; i++) {
                threads[i] = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0; i < 10000; i++) {
                            increase();
                        }
                    }
                });
                threads[i].start();
            }
    
            while (Thread.activeCount() > 1) {
                Thread.yield();
            }
            System.out.println(race);
        }
    }

     

    这个例子有些网友反馈会进入死循环,我后面也发现了,在IDEA的RUN模式下确实会陷入死循环,通过 Thread.currentThread().getThreadGroup().list(); 代码可以打印出当前的线程情况如下:

    java.lang.ThreadGroup[name=main,maxpri=10]
        Thread[main,5,main]
        Thread[Monitor Ctrl-Break,5,main]

     

    可以看到,除了Main方法线程后,还有一个Monitor Ctrl-Break线程,这个线程是IDEA用来监控Ctrl-Break中断信号的线程。

    解决死循环的办法:如果是IDEA,可以使用DEBUG模式运行就可以,或者使用下面这段代码。

    import java.util.concurrent.CountDownLatch;
    
    /**
     * @author joonwhee
     * @date 2019/7/6
     */
    public class VolatileTest {
        
        public static volatile int race = 0;
    
        private static final int THREADS_COUNT = 20;
    
        private static CountDownLatch countDownLatch = new CountDownLatch(THREADS_COUNT);
    
        public static void increase() {
            race++;
        }
    
        public static void main(String[] args) throws InterruptedException {
            Thread[] threads = new Thread[THREADS_COUNT];
            for (int i = 0; i < THREADS_COUNT; i++) {
                threads[i] = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0; i < 10000; i++) {
                            increase();
                        }
                        countDownLatch.countDown();
                    }
                });
                threads[i].start();
            }
            countDownLatch.await();
            System.out.println(race);
        }
    }

     

    上面这个例子在volatile关键字详解文中用过,我们知道,运行完这段代码之后,并不会获得期望的结果,而且会发现每次运行程序,输出的结果都不一样,都是一个小于200000的数字。

     

    通过分析字节码我们知道,这是因为volatile只能保证可见性,无法保证原子性,而自增操作并不是一个原子操作(如下图所示),在并发的情况下,putstatic指令可能把较小的race值同步回主内存之中,导致我们每次都无法获得想要的结果。那么,应该怎么解决这个问题了?

     

    解决方法:

    首先我们想到的是用synchronized来修饰increase方法。

     

    使用synchronized修饰后,increase方法变成了一个原子操作,因此是肯定能得到正确的结果。但是,我们知道,每次自增都进行加锁,性能可能会稍微差了点,有更好的方案吗?

     

    答案当然是有的,这个时候我们可以使用Java并发包原子操作类(Atomic开头),例如以下代码。

    我们将例子中的代码稍做修改:race改成使用AtomicInteger定义,“race++”改成使用“race.getAndIncrement()”,AtomicInteger.getAndIncrement()是原子操作,因此我们可以确保每次都可以获得正确的结果,并且在性能上有不错的提升(针对本例子,在JDK1.8.0_151下运行)。

     

    通过方法调用,我们可以发现,getAndIncrement方法调用getAndAddInt方法,最后调用的是compareAndSwapInt方法,即本文的主角CAS,接下来我们开始介绍CAS。

    getAndAddInt方法解析:拿到内存位置的最新值v,使用CAS尝试修将内存位置的值修改为目标值v+delta,如果修改失败,则获取该内存位置的新值v,然后继续尝试,直至修改成功。

     

    CAS是什么?

    CAS是英文单词CompareAndSwap的缩写,中文意思是:比较并替换。CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。

    CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。

     

    源码分析

    上面源码分析时,提到最后调用了compareAndSwapInt方法,接着继续深入探讨该方法,该方法在Unsafe中对应的源码如下。

    可以看到调用了“Atomic::cmpxchg”方法,“Atomic::cmpxchg”方法在linux_x86和windows_x86的实现如下。

    linux_x86的实现:

    windows_x86的实现:

    Atomic::cmpxchg方法解析:

    mp是“os::is_MP()”的返回结果,“os::is_MP()”是一个内联函数,用来判断当前系统是否为多处理器。

    1. 如果当前系统是多处理器,该函数返回1。
    2. 否则,返回0。

    LOCK_IF_MP(mp)会根据mp的值来决定是否为cmpxchg指令添加lock前缀。

    1. 如果通过mp判断当前系统是多处理器(即mp值为1),则为cmpxchg指令添加lock前缀。
    2. 否则,不加lock前缀。

    这是一种优化手段,认为单处理器的环境没有必要添加lock前缀,只有在多核情况下才会添加lock前缀,因为lock会导致性能下降。cmpxchg是汇编指令,作用是比较并交换操作数。

     

    intel手册对lock前缀的说明如下:

    1. 确保对内存的读-改-写操作原子执行。在Pentium及Pentium之前的处理器中,带有lock前缀的指令在执行期间会锁住总线,使得其他处理器暂时无法通过总线访问内存。很显然,这会带来昂贵的开销。从Pentium 4,Intel Xeon及P6处理器开始,intel在原有总线锁的基础上做了一个很有意义的优化:如果要访问的内存区域(area of memory)在lock前缀指令执行期间已经在处理器内部的缓存中被锁定(即包含该内存区域的缓存行当前处于独占或以修改状态),并且该内存区域被完全包含在单个缓存行(cache line)中,那么处理器将直接执行该指令。由于在指令执行期间该缓存行会一直被锁定,其它处理器无法读/写该指令要访问的内存区域,因此能保证指令执行的原子性。这个操作过程叫做缓存锁定(cache locking),缓存锁定将大大降低lock前缀指令的执行开销,但是当多处理器之间的竞争程度很高或者指令访问的内存地址未对齐时,仍然会锁住总线。
    2. 禁止该指令与之前和之后的读和写指令重排序。
    3. 把写缓冲区中的所有数据刷新到内存中。

    上面的第1点保证了CAS操作是一个原子操作,第2点和第3点所具有的内存屏障效果,保证了CAS同时具有volatile读和volatile写的内存语义。

     

    CAS的缺点:

    CAS虽然很高效的解决了原子操作问题,但是CAS仍然存在三大问题。

    1. 循环时间长开销很大。
    2. 只能保证一个变量的原子操作。
    3. ABA问题。

     

    循环时间长开销很大:

    CAS 通常是配合无限循环一起使用的,我们可以看到 getAndAddInt 方法执行时,如果 CAS 失败,会一直进行尝试。如果 CAS 长时间一直不成功,可能会给 CPU 带来很大的开销。

     

    只能保证一个变量的原子操作:

    当对一个变量执行操作时,我们可以使用循环 CAS 的方式来保证原子操作,但是对多个变量操作时,CAS 目前无法直接保证操作的原子性。但是我们可以通过以下两种办法来解决:1)使用互斥锁来保证原子性;2)将多个变量封装成对象,通过 AtomicReference 来保证原子性

     

    什么是ABA问题?ABA问题怎么解决?

    CAS 的使用流程通常如下:1)首先从地址 V 读取值 A;2)根据 A 计算目标值 B;3)通过 CAS 以原子的方式将地址 V 中的值从 A 修改为 B。

    但是在第1步中读取的值是A,并且在第3步修改成功了,我们就能说它的值在第1步和第3步之间没有被其他线程改变过了吗?

    如果在这段期间它的值曾经被改成了B,后来又被改回为A,那CAS操作就会误认为它从来没有被改变过。这个漏洞称为CAS操作的“ABA”问题。Java并发包为了解决这个问题,提供了一个带有标记的原子引用类“AtomicStampedReference”,它可以通过控制变量值的版本来保证CAS的正确性。因此,在使用CAS前要考虑清楚“ABA”问题是否会影响程序并发的正确性,如果需要解决ABA问题,改用传统的互斥同步可能会比原子类更高效。

     

    推荐阅读

    如何写一份让 HR 眼前一亮的简历(附模板)

    字节、美团、快手核心部门面试总结(真题解析)

    面试阿里,HashMap 这一篇就够了

    面试必问的 MySQL,你懂了吗?

    面试必问的线程池,你懂了吗?

    4 年 Java 经验,阿里网易拼多多面试总结、心得体会

    跳槽,如何选择一家公司

    如何准备好一场大厂面试

    MySQL 8.0 MVCC 核心原理解析(核心源码)

    921天,咸鱼到阿里的修仙之路

    复习2个月拿下美团offer,我都做了些啥

     

     

    另外,我还准备了很多大厂面试资料、0基础自学教程,由于不能放外链,所以有需要的小伙伴去公众号【程序员囧辉】回复【资料】自行获取好了。

    展开全文
  • CAS实现单点登录(SSO)经典完整教程

    万次阅读 多人点赞 2011-08-06 11:01:38
    一、简介 1、cas是有耶鲁大学研发的单点登录服务器 2、本教材所用环境 Tomcat7.2JDK6CAS Service 版本 cas-server-3.4.8-rele

     目录

        一、简介

        二、生成证书

        三、配置服务端

       四、配置客户端

       五、常见问题说明


        一、简介

                    1、cas是有耶鲁大学研发的单点登录服务器

                     2、本教材所用环境

     

    • Tomcat7.2
    • JDK6
    • CAS Service 版本    cas-server-3.4.8-release
    • CAS Client版本      cas-client-3.2.1-release                                

     

        二、生成证书

                                证书对于实现此单点登录非常之重要,证书是服务器端和客户端安全通信的凭证,本教程只是演示,所有用了

                        JDK自带的证书生成工具keytool。当然在实际项目中你可以到专门的证书认证中心购买证书。

                                中文官方网站:http://www.verisign.com/cn/

                       1、用JDK自带的keytool生成证书

                                

    命令:keytool -genkey -alias  smalllove -keyalg RSA -keystore D:/keys/smallkey

                       此命令是生成一个证书,其中 smalllove 是证书别名

     

         此命令的执行如图所示:

                        

                          其中名字与姓氏这一最好写你的 域名,如果在单击测试你可以在C:\Windows\System32\drivers\etc\hosts文件中映射一个虚拟域名,

                  注意不要写IP。

               2、导出证书

                    

    命令:C:\>keytool -export -file d:/keys/small.crt -alias smalllove -keystore d:/keys/smallkey

                    如图:

     

                          

                   密码为上步设置的密码。

               3、把证书导入到客户端JDK中。

                    

    命令:keytool -import -keystore C:\Java\jdk1.6.0_21\lib\security\cacerts -file D:/keys/small.crt -alias smalllove

               此命令是把证书导入到JDK中。

     

               如图:

                

              到此证书导入成功。

               注意:在此步有可能出现如下错误

         

               C:\>keytool -import -keystore C:\Java\jdk1.6.0_21\lib\security\cacerts -file D:/keys/small.crt -alias smalllove
                  输入keystore密码:
                keytool错误: java.io.IOException: Keystore was tampered with, or password was incorrect

                         次错误的解决方法是,把%JAVA_HOME%\lib\security下的cacerts文件删除掉,在执行。

     

                     

        三、配置服务端

                          1、 下载CAS的服务端,解压,把解压后的文件中modules文件夹中的cas-server-webapp-3.4.8.war文件拷贝的%TOMCAT_HOME%\webapps

                   下,并修改文件名为:cas.war。

                                 源码下载地址:https://github.com/Jasig/cas/releases

                          2、修改%TOMCAT_HOME%\conf\server.xml文件

                                   去掉此文件83到93行之间的注释,修改为:

                           

    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                   maxThreads="150" scheme="https" secure="true"
                   clientAuth="false" sslProtocol="TLS" 
    			   keystoreFile="D:/keys/smallkey"  <!--在2.1中生成的证书的位置-->
    			   keystorePass="smalllove"/>       <!--在2.1中设置的密码-->

                         3、以上配置完成访问http://yourhost:8443/cas出现一下页面

     

                                       

                              点击继续浏览会出现

                                             

                             输入用户名admin和密码admin登录则会出现

                                          

                             登录成功。

                             至此,说明服务端配置成功。

       四、配置客户端

                       1、添加客户端到你的项目中

                              ·手动下载下载cas-client,地址:http://downloads.jasig.org/cas-clients/,然后解压cas-client-3.1.12.zip,在modules文件夹中有需要的jar包,                         请根据自己的项目情况选择使用,把相应的jar包放到你项目WEB-INF/lib下。

                       ·使用maven

                                  

    <!-- cas -->
    <dependency>
    	<groupId>org.jasig.cas.client</groupId>
    	<artifactId>cas-client-core</artifactId>
    	<version>3.1.12</version>
    </dependency>

                    2、在客户端项目的web.xml配置过滤器

                            

    <!-- ======================== 单点登录开始 ======================== -->
    	<!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置 -->
    	<listener>
    		<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
    	</listener>
    
    	<!-- 该过滤器用于实现单点登出功能,可选配置。 -->
    	<filter>
    		<filter-name>CAS Single Sign Out Filter</filter-name>
    		<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
    	</filter>
    	<filter-mapping>
    		<filter-name>CAS Single Sign Out Filter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    
    	<!-- 该过滤器负责用户的认证工作,必须启用它 -->
    	<filter>
    		<filter-name>CASFilter</filter-name>
    		<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
    		<init-param>
    			<param-name>casServerLoginUrl</param-name>
    			<param-value>https://www.travel.com:8443/cas/login</param-value>
    			<!--这里的server是服务端的IP -->
    		</init-param>
    		<init-param>
    			<param-name>serverName</param-name>
    			<param-value>http://www.travel.com:8080</param-value><span style="color:#FF0000;"> ①</span>
    		</init-param>
    	</filter>
    	<filter-mapping>
    		<filter-name>CASFilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    
    	<!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->
    	<filter>
    		<filter-name>CAS Validation Filter</filter-name>
    		<filter-class>
    			org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
    		<init-param>
    			<param-name>casServerUrlPrefix</param-name>
    			<param-value>https://www.travel.com:8443/cas</param-value>
    		</init-param>
    		<init-param>
    			<param-name>serverName</param-name>
    			<param-value>http://www.travel.com:8080</param-value>  <span style="color:#FF0000;">②</span>
    		</init-param>
    	</filter>
    	<filter-mapping>
    		<filter-name>CAS Validation Filter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    
    	<!-- 该过滤器负责实现HttpServletRequest请求的包裹, 比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。 -->
    	<filter>
    		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
    		<filter-class>
    			org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
    	</filter>
    	<filter-mapping>
    		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    
    	<!-- 该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。 比如AssertionHolder.getAssertion().getPrincipal().getName()。 -->
    	<filter>
    		<filter-name>CAS Assertion Thread Local Filter</filter-name>
    		<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
    	</filter>
    	<filter-mapping>
    		<filter-name>CAS Assertion Thread Local Filter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    
    	<!-- ======================== 单点登录结束 ======================== -->

                 

     

     

       五、常见问题说明

                      错误一、

                               

             若出现以上错原因是:你在客户端的web.xml中①,②的配置有误。

                 错误二、

                             

    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: 
    PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: 
    unable to find valid certification path to requested target

                      若出现次错误是有与你客户端的证书有问题。重新导入你证书。

     

    展开全文
  • CAS实战教程

    2019-07-24 10:34:47
    本课程内容包括CAS简介、CAS架构简介、CAS覆盖安装、CAS配置SSL证书、CAS改为安全连接模式、CAS改为Tomcat安全连接模式、CAS改为JDBC动态连接模式、CAS重置密码参数配置、CAS重置密码开启邮箱SMTP服务、CAS重置密码...
  • 通过Proxy访问其它Cas应用  考虑这样一种场景:有两个应用App1和App2,它们都是受Cas Server保护的,即请求它们时都需要通过Cas Server的认证。现需要在App1中通过Http请求访问App2,显然该请求将会被App2配置的Cas...
  • CAS详解

    千次阅读 2017-06-18 00:51:18
    CAS详解
  • CAS理解

    2019-02-01 15:03:47
    CAS 一、什么是CAS 概念 CAS(compare and swap)即比较并交换。它是解决多线程的环境下使用锁造成性能损耗的一种机制。 内容 CAS操作一般包含三个操作数——内存位置(V)、预期原值(A)和新值(B) 当且仅当预期...
  • CAS protocol

    2018-06-17 00:32:43
    翻译自:CAS 官网CAS protocolThe CAS protocol is a simple and powerful ticket-based protocol developed exclusively for CAS. A complete protocol specification may be found here.It involves one or many ...
  • cas Cas20ProxyReceivingTicketValidationFilter

    千次阅读 2018-04-13 05:52:00
    Cas20ProxyReceivingTicketValidationFilter 继承AbstractTicketValidationFilter,这里有几个模板方法。例如getTicketValidator,preFilter. onSuccessfulValidation, onFailedValidation等。大的逻辑在...
  • cas 协议

    千次阅读 2019-11-25 17:23:32
    CAS协议是一种简单且功能强大的基于票证(ticket)的协议。它涉及一个或多个客户端和一台服务器。中央身份验证服务(CAS)是Web的单点登录/单点退出协议。用户向中央CAS Server应用程序提供一次凭据(例如用户ID和密码...
  • 环境要求 ... CAS(一)搭建CAS - server服务器   二、配置hosts,加入如下配置 127.0.0.1 cas.server.com 127.0.0.1 cas.client1.com 三、搭建Springboot项目 项目名为cas-clientB,项...
  • PHP使用phpCAS对接CAS单点登陆系统

    千次阅读 2019-09-11 15:22:40
    PHP使用phpCAS对接CAS单点登陆系统综述`CAS`单点登陆原理搭建`CAS SSO`SERVER服务端下载`phpCAS`客户端phpCAS客户端配置PHP开发对接注意 ...了解CAS单点登录原理解析 搭建CAS SSOSERVER服务端; ...
  • 浅谈CAS以及CAS在java中应用

    万次阅读 多人点赞 2019-01-02 21:48:20
    浅谈CAS以及CAS在java中应用 cas是什么? cas是compareandswap的简称,从字面上理解就是比较并更新,简单来说:从某一内存上取值V,和预期值A进行比较,如果内存值V和预期值A的结果相等,那么我们就把新值B更新到...
  • CAS 完全解析

    千次阅读 2020-06-14 22:46:13
      查看JUC包源码时,会发现JUC包中很多操作都是基于CAS基础实现的,CAS是一种无锁算法,在不阻塞程序的情况下,提供多线程安全可靠的数据操作。   所谓的CAS,即是compareAndSwap,比较并替换。CAS操作中,包括...
  • 环境要求 ... CAS(一)搭建CAS - server服务器   二、修改application.properties 静态验证的配置,需要注释: ## # CAS Authentication Credentials # #cas.authn.accept.users=user::12...
  • SpringBoot 搭建CAS 客户端 和CAS 服务端

    千次阅读 2019-05-06 10:11:35
    第一步:搭建CAS5.3 服务端 Github 下载CAS5.3 服务端版本:https://github.com/apereo/cas-overlay-template/tree/5.3 注意:最新的master分支使用的需要java11,该分支使用Gradle工程由于我使用的是java8,采用...
  • CAS(一)搭建CAS - server服务器

    万次阅读 多人点赞 2018-10-25 14:40:14
    CAS 5.2 tomcat 8+ about CAS cas document https://apereo.github.io/cas/5.2.x/index.html cas server 客户端模板下载 https://github.com/apereo/cas-overlay-template   步骤 一、修改hosts文件,模拟...
  • 环境要求 ... CAS(一)搭建CAS - server服务器   二、配置hosts,加入如下配置 127.0.0.1 cas.server.com 127.0.0.1 cas.client1.com 三、搭建SpringMVC项目 项目名为cas-clientA,项目...
  • CAS使用

    千次阅读 2018-08-31 10:31:02
    CAS的官方网址是: https://www.apereo.org/projects/cas 工程代码网址:https://github.com/Jasig/cas 使用参考:http://www.imooc.com/article/3576 问题 1.未认证授权的服务 不允许使用CAS来认证您访问的...
  • CAS配置

    千次阅读 2018-12-14 22:50:03
    CAS默认使用的是HTTPS协议,如果使用HTTPS协议需要SSL安全证书(需向特定的机构申请和购买) 。...(1)修改cas的WEB-INF/deployerConfigContext.xml  找到下面的配置 &lt;bean class="org.jasig.cas.a...
  • CAS策略

    2018-09-04 22:55:35
    CAS是Compare And Swap的缩写,CAS是一种解决部分并发情况下的解决方案,比如多线程环境下变量的自增就可以用CAS策略解决,一般而言,CAS有三个操作数,一个是目标变量V,一个是新值N,一个是目标变量期望值E,当...
  • 一、CAS服务端搭建 1.1 CAS支持Http登录配置 CAS默认是要https的链接才能登录的,不过学习的话是可以先去掉https限制,本博客介绍的是基于Cas5.3.1的,之前改过4.0,4.2.7的,详情见...
  • 问题描述:cas单点登录可以登录成功,就是一个浏览器上 成功通过了cas单点登录,过了很久 ,不做任何操作(这时cas的验证 ST可能已经过期),当再在该浏览器上进行cas登录操作时就会报错。 错误截图: ![](H:\UVISL...
  • CAS客户端和服务端部署

    千次阅读 2017-06-22 09:17:23
    cas
  • CAS操作

    千次阅读 2017-11-28 17:30:58
    CAS操作,总线锁定,缓存锁定
  • CAS 单点登录系统 连接不上去. 我用的是cas 用数据库中的 账号密码登录 数据库密码也确认过没问题 . 连的上 后来发现原来是 cas 访问页 修改的时候, 可能是因为文件没有引正确,导致的连接不上, 替换原来...
  • CAS原理分析

    万次阅读 多人点赞 2018-08-13 10:26:11
    CAS的英文为Compare and Swap 翻译为比较并交换。 CAS加volatile关键字是实现并发包的基石。没有CAS就不会有并发包,synchronized是一种独占锁、悲观锁,java.util.concurrent中借助了CAS指令实现了一种区别于...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,125
精华内容 14,850
关键字:

cas