概念

CAS (compareAndSet(最新) 或compareAndSwap JDK不同版本名称不同)

当且仅当原值==期望值时,才更新为新值

具体表现为:

当一个线程需要修改某个值时,会将原值(即当前线程中该值的副本)跟主内存中的这个值进行比较,如果相等,就更新为新值.

例如 count++; 当前线程中count=2(原值); 主内存中的count=2(即期望值);此时count 就执行++操作,更新为count=3(新值)
如果此时当前线程中count=2(原值); 主内存中的count=3(即期望值);就不做任何操作.因为count=3就证明该值被其它线程改过
由此实现cas操作

为什么这么做:

是一种锁优化的形式,避免上重量级锁.

安全性思考:
  1. CAS操作本身会不会有线程安全问题?
    答:是CPU指令级的操作 不能被打断 所以不存在线程安全问题
  2. 如何解决ABA问题?
    答:加版本号控制

在JUC包下,凡是以Atomic开头的类都是用CAS操作保证线程安全,所以在实际开发中,例如遇到多线程递增计数需求时,可使用AtomicXXX等类提高多线程执行效率

ReentrantLock(可重入锁)与synchronized

其实跟sychronized 作用差不多,相当于是JDK1.5之后的sychronized 在JDK中的实现
本质上的区别在于sychronized 是JVM中的实现(不同的JVM,sychronized 的实现可以不同),ReentrantLock是JDK中的实现
在Java中,实现同步操作可以使用sychronized 或者Lock.lock(),Lock.unlock()两种方式锁住需要同步的代码块

但是在早期JDK版本中 加锁的操作是直接通过JVM通知操作系统使用内存屏障的原理进行控制 加锁操作直接进入内核态
后来的JDK对sychronized 进行了锁升级的优化,优化后的sychronized 操作步骤如下:

  1. 偏向锁 即 当前线程A进入同步代码块之后,会使用Mark Word标记该线程A已进入,以便后续线程进入时进行比较,如果还是A线程再次进入就不升级
  2. 自旋锁 即 当B线程进入时,此时偏向锁就会升级为自选锁,在等待A线程执行结束之前,会循环10次判断A线程是否执行完,超过10,锁升级
    偏向锁和自旋锁都是在JVM中完成的,都属于用户态
  3. 重量级锁 即 通过JVM通知操作系统进行线程调度 属于内核态

通过了解sychronized 的实现思路 对比ReentrantLock的实现
ReentrantLock就是将sychronized 的底层通过Java语言来实现 所以在实际开发使用当中 用法没有太大区别

所以使用ReentrantLock替代sychronized 是没问题的 就好比使用Lock.lock(),Lock.unlock()方式或sychronized 实现锁定同步代码块

ReentrantLock还有其它特性:

  1. tryLock 尝试锁,如果锁不住,可以执行哪些操作
  2. lockInterupptibly 打断锁
  3. 公平锁

ReentrantLock的实现原理:CAS
ReentrantLock与sychronized 的最大区别在于:ReentrantLock可以实现公平锁 而sychronized 是非公平的

公平与非公平锁

其实现主要依赖AQS(AbstractQueuedSynchronizer)这个类
原理:CAS 在AbstractQueuedSynchronizer维护了一个双向链表 和一个volatile修饰的state
公平锁:当新的线程进来时,进入双向链表,再进行state(本质上就是那把锁) 的竞争
非公平锁:当新的线程进来时,直接进入state 的竞争

JDK中其它使用CAS实现的锁

CountDownLatch 倒数门闩 用来等线程结束之后操作

CyclicBarrier N个线程满了 一起发车

Phaser 分段锁 遗传算法 分段栅栏 CyclicBarrier 升级版 颗粒度更细

ReadWriteLock 读写锁 即共享锁和排它锁

Semaphore 信号灯 限流 最多允许N个线程同时执行

Exchanger 交换器 线程之间交换变量值

LockSupport park()和unpark() 本质上和wait() notify() 一样

重点看下读写锁ReadWriteLock

import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockTest {private static Lock lock = new ReentrantLock();private static int value;static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();static Lock readLock = readWriteLock.readLock();static Lock writeLock = readWriteLock.writeLock();public static void read(Lock lock) {try {lock.lock();Thread.sleep(1000);System.out.println("read over!");//模拟读取操作} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}public static void write(Lock lock, int v) {try {lock.lock();Thread.sleep(1000);value = v;System.out.println("write over!");//模拟写操作} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}public static void main(String[] args) {//        Runnable readR = ()-> read(lock);Runnable readR = ()-> read(readLock);//        Runnable writeR = ()->write(lock, new Random().nextInt());Runnable writeR = ()->write(writeLock, new Random().nextInt());for(int i=0; i<18; i++) new Thread(readR).start();for(int i=0; i<2; i++) new Thread(writeR).start();}
}

这里的readLock 读锁 是一种乐观锁 就是做读操作时 不排他 可以多线程并发去读
而writeLock 写锁 是一种悲观锁 也是排他锁
读写不同的操作使用不同类型的锁 本质上体现的是应对高并发时读写分离的思想
ReadWriteLock是Java程序中的锁, 但与数据库层面的悲观锁乐观锁思想上有相似之处

CAS,ReentrantLock和synchronized总结相关推荐

  1. ReentrantLock和synchronized两种锁定机制

    ReentrantLock和synchronized两种锁定机制 应用synchronized同步锁 把代码块声明为 synchronized,使得该代码具有 原子性(atomicity)和 可见性( ...

  2. 面试官:你说说ReentrantLock和Synchronized区别!

    大家好!又和大家见面了.为了避免面试尴尬,今天同比较通俗语言和大家聊下ReentrantLock和Synchronized区别!另外:整理了一份Java面试宝典完整版PDF,已成文档 使用方式 Syn ...

  3. 面试官:你说说ReentrantLock和Synchronized区别

    目录 使用方式 实现方式 公平和非公平 可重入锁 可中断的 条件队列 总结 大家好!又和大家见面了.为了避免面试尴尬,今天同比较通俗语言和大家聊下ReentrantLock和Synchronized区 ...

  4. ReentrantLock与synchronized

    1.ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候和中断锁等候线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的 ...

  5. Java中的ReentrantLock和synchronized两种锁定机制的对比

    原文:http://www.ibm.com/developerworks/cn/java/j-jtp10264/index.html 多线程和并发性并不是什么新内容,但是 Java 语言设计中的创新之 ...

  6. Java多线程中使用ReentrantLock、synchronized加锁 简单举例

    Java多线程中使用ReentrantLock.synchronized加锁 简单举例 public class Demo {final static Lock lock = new Reentran ...

  7. ReentrantLock和synchronized锁

    ReentrantLock和synchronized锁 这两个锁都是独占锁,所谓独占,就是我在用,你不准用,当锁定时,其他线程必须等待运行的线程结束才能分得资源. 那么,两个独占锁又有什么不同呢,简单 ...

  8. reentrantLock 和 synchronized 哪个性能高?

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:一个线程池 bug 引发的 GC 思考!个人原创+1博客:点击前往,查看更多 链接:https://segmen ...

  9. Java 并发编程中使用 ReentrantLock 替代 synchronized 关键字原语

    标签: Java 5 引入的 Concurrent 并发库软件包中,提供了 ReentrantLock 可重入同步锁,用来替代 synchronized 关键字原语,并可提供更好的性能,以及更强大的功 ...

最新文章

  1. 【视频】vue $watch监控数据的变化
  2. 内存分配详解 malloc, new, HeapAlloc, VirtualAlloc,GlobalAlloc
  3. c语言课程设计加密程序,C语言课程设计文件加密解密.doc
  4. mysql 错误连接锁死_MySQL 8.0.19支持输入3次错误密码锁定账户功能(例子)
  5. SSM - 全局跨域处理
  6. 力控组态软件 mysql_组态软件国内那家做的好?推荐几个比较一下
  7. 深度学习学习笔记-双向LSTM-CRF模型论文研读
  8. java如何去掉文件后缀名_JAVA 递归批量更改文件后缀名 删除后缀
  9. 《数学建模与数学实验》第5版 插值与拟合 习题7.6
  10. Volley 源码解析(一)
  11. 屏幕尺寸、分辨率、像素密度三者关系
  12. 田口设计(正交设计)——参数设置方法
  13. 用计算机制作演示文稿教案博客,制作演示文稿[教案].doc
  14. 系统之家U盘 win10默认网关是什么
  15. ODN中主干光交和配线光交的数量比例
  16. centos7 | All matches were filtered out by modular filtering for argument: mysql-community-server
  17. mysql right函数
  18. Windows下利用Chrome调试IOS设备页面
  19. 【Oracle】快速向表中插入大量数据Oracle中append与Nologging
  20. php导出excel无边框线,phpexcel设置边框不全或者只有竖线问题解决方法

热门文章

  1. c语言编程实践题,C语言实践编程题
  2. 机器学习-增量训练方法
  3. 基于Dragonboard410c的智能音箱(四)
  4. 嵌入式 ssl协议详解
  5. 熬夜怒肝,保姆级Python学习路线,起飞!
  6. 深入剖析 grep 命令
  7. html的绝对定位脱离文档流吗,子元素position:absolute定位之后脱离文档流,怎么使子元素撑开父元素...
  8. 单点登录的简单理解(SSO)
  9. 块储存、对象存储、文件存储的区别和联系
  10. STM8L151 DAC