| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> Java的锁机制:synchronized和CAS -> 正文阅读 |
|
[Java知识库]Java的锁机制:synchronized和CAS |
提到Java的知识点一定会有多线程,JDK版本不断的更迭很多新的概念和方法也都响应提出,但是多线程和线程安全一直是一个重要的关注点。比如说我们一入门就学习的synchronized怎么个实现和原理,还有总是被提到的CAS是啥,他和synchronized关系是啥?这里大概会让你对这些东西有一个认识。 一 为什么要用锁 比如我现在搞一个多线程的demo,我的本意是每个线程都高呼“ZPNB!”,我写下了如下的代码。
没有加锁的情况是这样的,看起来很乱我希望他们每个人都喊十遍然后下一个人,显然下面的结果不满意
但是如果我把synchronized的注释取消就变成了我想要的依次每人喊十遍
这就突出了锁的重要性,我们希望有些线程能按照我们希望的一个顺序依次来执行,而不是先到先得的。 二 synchronized怎么实现的 那如果没获取到监视器怎么办,有个同步队列的东西,你没得到监视器就等一等,等上一个获取监视器的exit推出监视器你再根据队列顺序去再获取,当然可能在这个再获取的过程碰到一个“新来的”没进队列直接跟你抢,你还没抢过,那你就还要重复之前的等待过程。 其实这里还涉及一个锁的“happen before”的概念(“ A hapen-bfore B,那么 A 的结果对 B 是可见的”),就是上一个线程如果对某些值有改写,后一个应该在这个基础上改写的原则,假设一个计算程序,值都改了,新的线程你还在拿原先的值再去计算是不对的,应该是在新的值上面再去做操作,这样多线程协作才有实际意义。 以下是关于synchronized作用范围(基本是实际对象或者是类对象,如果你是类对象的话,那你new多少个实例对象还是被锁的。) 三 CAS来者何人 实际二者应该是同级的概念,大家都是锁,synchronized是悲观锁,基本就是来一个线程就是锁起来,阻塞同步的。认为任何操作都有可能是冲突,所以按照最坏的情况来处理,线程竞争阻塞了就阻塞,阻塞结束了就唤醒阻塞的进程。 CAS就是compare and swap ,不是直接锁起来,大概意思就是: CAS对于线程竞争冲突的情况相对来说就温柔一些,他会有自己的重试机制,就是这次不行我等一会再去看看,而不是直接阻塞挂起再唤醒的状态,这样太耗费时间了。 在Java.util,ConCurrent包里面很多都是用CAS来处理同步的问题,而不是直接来个synchronized来修饰。 四synchronized和CAS孰优孰劣 比如说CAS也会有自己的问题,最主要的有:ABA,自旋时间过长和只能保证一个共享变量的原子操作,虽然说都要相关的解决方案: synchronized自身也在不断地优化自身,甚至也借鉴了CAS的思想在1.6里面。为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”,在Java SE 1.6中,锁一共有4种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态。 偏向锁(通过线程ID来看对象头和栈帧里面查找线程ID(记录的线程ID就是偏向的线程ID),有就获取没有就尝试CAS设置自己为偏向的线程) 当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需简单地测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。如果测试成功,表示线程已经获得了锁。如果测试失败,则需要再测试一下Mark Word中偏向锁的标识是否设置成1(表示当前是偏向锁),如果没有设置,则使用CAS竞争锁;如果设置了,则尝试使用CAS将对象头的偏向锁指向当前线程。 轻量级锁 重量级锁 这么看来synchronized并不是那么不堪,未必你用CAS实现的就一定在某些环境比synchronized这个“元老”强。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 19:27:14- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |