上篇文章,我们主要讲了解决多线程之间共享数据的核心问题和解决方案,也讲了锁的简单分类。

那么,这把锁,我们应该怎么去实现呢?如果你是java语言设计者,你又会怎么去设计这个线程锁呢?

直觉告诉我们,我们可以设计一个对象或属性,用来代表锁。比如,你把共享数据区当成抽屉,那这个抽屉就可设计出有锁,有钥匙,其实锁和钥匙,就是这个抽屉的必要属性。否则,这个抽屉,也就失去主要用途了。

是的,java设计者,也是这样的想的。

在JVM的规范中,有这么一些话:  
  “在JVM中,每个对象和类在逻辑上都是和一个监视器相关联的”  
    “为了实现监视器的排他性监视能力,JVM为每一个对象和类都关联一个锁”  
  “锁住了一个对象,就是获得对象相关联的监视器”

这三段定义,也许比较模糊又或者比较难懂 。在这里,我们就把监视器,想象成个抽屉就好了,有抽屉就有锁。要访问抽屉,就要拥有这个抽屉的钥匙。

在java世界中,一般用这几个方法来实现锁与线程同步:synchronized,wait/notify/notifyAll.

我们知道,synchronized是用来锁定同步代码块或方法或类,那么synchronized,又是如何实现 的呢?

Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的。但是监视器锁本质又是依赖于底层的操作系统的Mutex Lock(互斥锁)来实现的。而操作系统实现线程之间的切换这就需要从用户态转换到核心态,这个成本非常高,状态之间的转换需要相对比较长的时间,这就是为什么Synchronized效率低的原因。因此,这种依赖于操作系统Mutex Lock所实现的锁我们称之为“重量级锁”。JDK中对Synchronized做的种种优化,其核心都是为了减少这种重量级锁的使用。JDK1.6以后,为了减少获得锁和释放锁所带来的性能消耗,提高性能,引入了“轻量级锁”和“偏向锁”。

那么这个轻量级锁,又是如何实现的呢?

CAS算法。

什么是CAS?简单来讲,它就是一条CPU原子指令:Compare and Swap, 翻译成比较并交换。

CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

简单来说,CPU从指令层级来保证数据的原子性。要么改成最新值,要么什么不做。

这个就是无锁或轻量级锁的核心知识。

java高并发核心要点|系列2|锁的底层实现原理的更多相关文章

  1. java高并发核心要点|系列3|锁的底层实现原理|ABA问题

    继续讲CAS算法,上篇文章我们知道,CAS算法底层实现,是通过CPU的原子指令来实现. 那么这里又有一个情景: 话说,有一个线程one从内存位置V中取出A,这时候另一个线程two也从内存中取出A,并且 ...

  2. java高并发核心要点|系列文章

    java高并发核心要点|系列1|开篇 java高并发核心要点|系列2|锁的底层实现原理 java高并发核心要点|系列3|锁的底层实现原理|ABA问题 java高并发核心要点|系列4|CPU内存指令重排 ...

  3. java高并发核心要点|系列1|开篇

    在java高并发编程,有几个很重要的内容: 1.CAS算法 2.CPU重排序 3.缓存行伪共享 我们先来说说高并发世界中的主要关键问题是什么? 是数据共享. 因为多线程之间要共享数据,就会遇到各种问题 ...

  4. java高并发核心要点|系列4|CPU内存指令重排序(Memory Reordering)

    今天,我们来学习另一个重要的概念. CPU内存指令重排序(Memory Reordering) 什么叫重排序? 重排序的背景 我们知道现代CPU的主频越来越高,与cache的交互次数也越来越多.当CP ...

  5. java高并发核心要点|系列5|CPU内存伪共享

    上节提到的:伪共享,今天我们来说说. 那什么是伪共享呢? 这得从CPU的缓存结构说起.以下如图,CPU一般来说是有三级缓存,1 级,2级,3级,越上面的,越靠近CPU的,速度越快,成本也越高.也就是说 ...

  6. 从菜鸟到大神:Java高并发核心编程(连载视频)

    任何事情是有套路的,学习是如此, Java的学习,更是如此. 本文,为大家揭示 Java学习的套路 背景 Java高并发.分布式的中间件非常多,网上也有很多组件的源码视频.原理视频,汗牛塞屋了. 作为 ...

  7. java高并发核心类 AQS(Abstract Queued Synchronizer)抽象队列同步器

    什么是AQS? 全称: Abstract Queued Synchronizer: 抽象队列同步器 是 java.util.concurrent.locks包下的一个抽象类 其编写者: Doug Le ...

  8. Java高并发和多线程系列 - 1. 线程基本概念

    1. 什么是线程? 线程和进程的区别 在了解线程的概念前,我们应该先知道什么是进程? 进程是操作系统的基本概念之一, 它是正在执行的程序实例. * 下面的一些进程的基本概念你可以了解下 ------- ...

  9. 【实战Java高并发程序设计 2】无锁的对象引用:AtomicReference

    AtomicReference和AtomicInteger非常类似,不同之处就在于AtomicInteger是对整数的封装,而AtomicReference则对应普通的对象引用.也就是它可以保证你在修 ...

随机推荐

  1. 数据科学中的R和Python: 30个免费数据资源网站

    1 政府数据 Data.gov:这是美国政府收集的数据资源.声称有多达40万个数据集,包括了原始数据和地理空间格式数据.使用这些数据集需要注意的是:你要进行必要的清理工作,因为许多数据是字符型的或是有 ...

  2. datagrid——jQuery EasyUI

    API文档:[http://www.jeasyui.com/documentation/datagrid.php] 一.创建datagrid 在页面上添加一个div或table标签,然后用jquery ...

  3. Hibernate初了解

    Hibernate是一个开放源代码的对象关系映射框架, 它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JD ...

  4. argparse:命令行参数解析详解

    简介# 本文介绍的是argparse模块的基本使用方法,尤其详细介绍add_argument内建方法各个参数的使用及其效果. 本文翻译自argparse的官方说明,并加上一些笔者的理解 Copy im ...

  5. cocos2dx[3.2](5) 屏幕适配

    1.两个分辨率 1.1.窗口分辨率 在AppDelegate.cpp中有个设置窗口分辨率的函数.该函数是设置了我们预想设备的屏幕大小,也就是应用程序窗口的大小. // glView->setFr ...

  6. 基于element表格的合并多个行实例

    官方示例地址:https://github.liubing.me/lb-element-table/zh/guide/ 效果图: 0.下载lb-table 并引入 import LbTable fro ...

  7. Java学习开发第一阶段总结

    前言: 按照学院的安排我专业应该在下学期学习Java课程,因为对技术的热爱,我选择了在本学期学习Java.俗话说得好“笨鸟先飞”,那我就先学习这门课程了. 第一阶段的学习总结: 在此次阶段任务相对比较 ...

  8. Spring中pom文件所需节点

    <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> &l ...

  9. awk对文件的奇偶行做处理

    { if(NR % 2 == 0) printf("%s\n", $0) else printf("%s, ", $1) } awk -f awk.awk da ...

  10. MySql 缓冲池(buffer pool) 和 写缓存(change buffer) 转

    应用系统分层架构,为了加速数据访问,会把最常访问的数据,放在缓存(cache)里,避免每次都去访问数据库. 操作系统,会有缓冲池(buffer pool)机制,避免每次访问磁盘,以加速数据的访问. M ...