在java高并发编程,有几个很重要的内容:

1.CAS算法

2.CPU重排序

3.缓存行伪共享

我们先来说说高并发世界中的主要关键问题是什么?

是数据共享。

因为多线程之间要共享数据,就会遇到各种问题。如下图:

如果两个线程同时写入,那怎么保证数据的一致性?是线程1先写,还是线程2先写,这是个问题。那要如何解决这个问题?

答案是:加锁。

比如,线程1先访问共享数据区,那么它就先把这块数据区锁起来。后面如果其他线程要访问这个共享区,首先要从线程1这里获取锁,才能进一步访问这个共享区。这里很好理解,

其实相当于这样的情景,你有一个抽屉,抽屉有把锁,这个锁的钥匙,在你手上,你就可以打开抽屉,往里面存放或拿取物件。其他人,要从这个抽屉里存放东西,必须征得你的同意,从你手上拿到钥匙,然后,他才能用这把钥匙打开抽屉,进行存放物件的动作。如下图:

回到高并发的线程世界,我们知道,可以用加锁来解决多线程访问共享数据区的问题。那问题又来了,那这把锁,先交给谁呢?怎么解决这个问题呢?

答案是:锁竞争。

多线程,如果在优先级一样的情况下,大家进行公平竞争?那怎么样才算公平竞争呢?一般情况下,我们都可以想到:先到先得。

是的,一般情况下,操作系统对线程竞争,都取用这个方式,这样也符合常理。

好,线程1来了,获得一把锁,对这个共享数据区进行锁定访问。那别的线程,只能等待这个线程“办完事”后,释放锁。这时,这些别的线程就进入等待状态。

现在问题,又来了,如果线程1只是对这个共享数据区进行读访问,是否有必要把这个数据区全面锁定,不让其他线程进行读访问呢?

没有必要!

怎么解决?

读写分离!

分别定义两把锁,一把读锁,一把写锁。写锁,还是对写有独占权。读锁,就可以无限量地分发给其他多个线程。这样不影响共享数据区的数据一致性。

其实,读写分离,是架构设计和数据库设计中一个很重要的设计思想,也是高性能的一种设计理念。

当然,锁有很多种,以下就是各种锁:

锁

优点

缺点

适用场景

偏向锁

加锁和解锁不需要额外的消耗,和执行非同步方法比仅存在纳秒级的差距。

如果线程间存在锁竞争,会带来额外的锁撤销的消耗。

适用于只有一个线程访问同步块场景。

轻量级锁

竞争的线程不会阻塞,提高了程序的响应速度。

如果始终得不到锁竞争的线程使用自旋会消耗CPU。

追求响应时间。

同步块执行速度非常快。

重量级锁

线程竞争不使用自旋,不会消耗CPU。

线程阻塞,响应时间缓慢。

追求吞吐量。

同步块执行速度较长。

好了,今天,我们主要讲多线程高并发编程的核心概念:线程锁。

明天,我们继续讲锁的底层实现原理。

java高并发核心要点|系列1|开篇的更多相关文章

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

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

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

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

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

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

  4. java高并发核心要点|系列2|锁的底层实现原理

    上篇文章,我们主要讲了解决多线程之间共享数据的核心问题和解决方案,也讲了锁的简单分类. 那么,这把锁,我们应该怎么去实现呢?如果你是java语言设计者,你又会怎么去设计这个线程锁呢? 直觉告诉我们,我 ...

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

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

  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. 2017.4.26 慕课网--Java 高并发秒杀API(一)

    Java高并发秒杀API系列(一) -----------------业务分析及Dao层 第一章 课程介绍 1.1 内容介绍及业务分析 (1)课程内容 SSM框架的整合使用 秒杀类系统需求理解和实现 ...

随机推荐

  1. PLSQL导出表的数据insert语句

    “Where clause”可以设置查询条件.设置好文件导出的路径(“Output file”),点击[Export]按钮,就可以导出INSERT语句了. 导出之后使用nodepad打开: 但是如果我 ...

  2. redis-主从复制、读写分离

    1.为什么要主从复制(一主多仆),读写分离:redis在作为缓存的时候,随着数据的不断增加,是有可能出现宕机的,这时候就出现了“单点故障”,解决方案就是进行主从复制,读写分离. 原理图:Master是 ...

  3. k8s, etcd 多节点集群部署问题排查记录

    目录 文章目录 目录 部署环境 1. etcd 集群启动失败 解决 2. etcd 健康状态检查失败 解决 3. kube-apiserver 启动失败 解决 4. kubelet 启动失败 解决 5 ...

  4. apache通过rewrite限制某个目录

    1.<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_URI} ^.*/tmp/* [NC] RewriteRule ...

  5. 阶段3 2.Spring_10.Spring中事务控制_4 spring中事务控制的一组API

    分析aop的 xml 的代码.更直观一些 事务提交和回滚就是我们重复的代码 spring业余事务管理器,我们拿过来直接用就可以 提交和回滚的后面直接调用释放.所以释放资源之类就是多余的 在绑定连接到线 ...

  6. jquery 教程网

  7. Function程序设计及应用

    Function也称为函数,它是SAP中一个独物的程序模式,一般是一段单独的程序代码,可独立执行或直接被SAP其他程序所调用.Function支持远程访问模式,即提供接口供SAP程序使用(如VB,.N ...

  8. javaScript 实现倒计时 + 获取网页中的文字

    一.倒计时 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <tit ...

  9. cocos2dx基础篇(7) 触碰事件

    cocos2dx游戏引擎的重点是在于移动设备的跨平台开发,而移动设备上的游戏大部分都是通过屏幕触碰来进行的.比如主菜单的按钮触碰,打飞机中飞机的触碰移动,都需要用到触碰操作.想一想之前讲的菜单按钮CC ...

  10. php配置 php-cgi.sock使用

    PHP配置文件: [global]pid = /run/php-fpm/php-fpm.piderror_log = /var/log/php-fpm/php-fpm.loglog_level = n ...