java并发编程笔记(一)——简介

线程不安全的类示例

public class CountExample1 {

    // 请求总数
public static int clientTotal = 5000; // 同时并发执行的线程数
public static int threadTotal = 200; public static int count = 0; public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadTotal);
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal ; i++) {
executorService.execute(() -> {
try {
semaphore.acquire();
add();
semaphore.release();
} catch (Exception e) {
log.error("exception", e);
}
countDownLatch.countDown();
});
}
countDownLatch.await();
executorService.shutdown();
log.info("count:{}", count); //最终得到的结果是小于5000的
} private static void add() {
count++;
}
}

并发:

同时拥有两个或者多个线程,如果程序在单核处理器上运行,多个线程将交替的换入换出内存,这些线程是同时“存在”的,每个线程都处于执行过程中的某个状态,如果运行在多核处理器上,程序中的每个线程都将分配到一个处理器核上,因此可以同时运行。

多个线程操作相同的资源,保证线程安全,合理使用资源

高并发(High Concurrency):

高并发是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。

java 内存模型(Java Memory Model,JMM)

java堆

  • 可以在运行时动态的分配内存大小;
  • 由于在运行时动态的分配大小,所以他的存取速度很慢;

java栈

  • 存取速度很快,仅次于计算机的寄存器,栈里的数据都是可以共享的;
  • 栈由于存放的数据大小与生存期是要求确定的,所以缺少一定的灵活性;

java线程引用对象的图示

cpu访问主存图示

当两个线程同时访问一个对象时,这两个线程持有的是这个对象的私有拷贝

cpu模型图

  • cpu访问寄存器的速度远大于在主存上的读取速度
  • 由于计算机的存储设备与处理器的处理速度有好几个数据量级的差距,所以存在了高速缓存区

java内存模型抽象结构图

java内存模型-同步八种操作

  • lock(锁定):作用于主内存的变量,把一个变量标识为一条线程独占状态
  • unlock(解锁):作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定
  • read(读取):作用主内存的变量,把一个变量值由主内存传输到线程的工作内存中,以便随后的load使用
  • load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中
  • use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎
  • assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋值给工作内存的变量
  • store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传送到主存中,以便随后的write的操作
  • write(写入):作用于主内存的变量,它把store操作从工作内存中一个变量的值传送到主内存的变量中

java内存模型-同步规则

  • 如果要把一个变量从主存中复制到工作内存,就需要按顺序的执行read和load操作,如果把变量从工作内存中同步回主内存中,就要按顺序的执行store和write操作。但java内存模型只要求上述操作必须按顺序执行,而没有保证必须是连续执行
  • 不允许read和load、store和write操作之一单独出现
  • 不允许一个线程丢弃它的最近assign的操作,即变量在工作内存中改变了之后,必须同步到主内存中
  • 不允许一个线程无原因的(没有发生过任何assign操作)把数据从工作内存同步回主内存中
  • 一个新的变量只能在主内存中诞生,不允许在工作内存中直接使用一个未被初始化(load和assign)的变量。即就是对一个变量实施use和store操作之前,必须先执行过了assign和load操作
  • 一个变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁,lock和unlock必须成对出现
  • 如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前需要重新执行load或assign操作初始化变量的值
  • 如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作,也不允许去unlock一个被其他线程锁定的变量
  • 对一个变量执行unlock操作之前,必须先把此变量同步到主内存中(执行store和write操作)

并发的优势和风险

优势

  • 同时处理多个请求,响应更快,负责的操作可以分成多个进程同时进行
  • 程序设计在某些情况下更简单,也可以有更多的选择
  • CPU能够在等待IO的时候做一些其他的事情

风险

  • 多个线程共享数据可能会产生与期望不相符的结果
  • 某个操作无法继续进行下去时,就会发生活跃性问题,比如死锁、饥饿等问题
  • 线程过多时会使得CPU频繁切换,调度时间增多,同步至机制;消耗过多内存

总结

  • CPU多级缓存:缓存一致性,乱序执行优化
  • java内存模型:JMM规定、抽象结构、同步八中操作及规则
  • java并发的优势与风险

java并发编程笔记(一)——并发编程简介的更多相关文章

  1. java web 学习笔记 - JSP标签编程

    1.JSP标签编程简介 标签编程在开发中并不常见,主要是为了更好的理解struts等框架的标签而打基础,完善相关知识体系. 标签编程分为: 一个继承自TagSupport的标签类,一个在WEB-INF ...

  2. 《Effective Java》读书笔记 - 10.并发

    Chapter 10 Concurrency Item 66: Synchronize access to shared mutable data synchronized这个关键字不仅保证了同步,还 ...

  3. Java Script 读书笔记 (四) 面向对象编程

    1. 对象,属性 前面看到对象里删除属性一直疑惑,什么是对象,为什么属性可以删除, 我印象里的属性还是停留在property, 总想不明白为什么属性竟然能够删除.直到看到标准库才明白,原来对象就是py ...

  4. 《深入理解Java虚拟机》笔记04 -- 并发锁

    Java虚拟机在操作系统层面会先尽一切可能在虚拟机层面上解决竞争关系,尽可能避免真实的竞争发生.同时,在竞争不激烈的场合,也会试图消除不必要的竞争.实现这些手段的方法包括:偏向锁.轻量级锁.自旋锁.锁 ...

  5. 《Effective Java》读书笔记 - 8.通用编程

    Chapter 8 General Programming Item 45: Minimize the scope of local variables local variables应该在他们要被用 ...

  6. [原创]java WEB学习笔记44:Filter 简介,模型,创建,工作原理,相关API,过滤器的部署及映射的方式,Demo

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  7. [原创]java WEB学习笔记04:Servlet 简介及第一个Servlet程序(配置注册servlet,生命周期)

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  8. LeapMotion控制器 java语言开发笔记--(LeapMotion控制器简介)

    (1)LeapMotion系统识别和追踪手,手指,以及根手指类似的工具,这个设备运行在一个极小的范围,这个范围拥有个高精度,高跟踪频率可以记录离散的点,手势,和动作. (2)LeapMotion控制器 ...

  9. [笔记][Java7并发编程实战手冊]系列文件夹

    推荐学习多线程之前要看的书. [笔记][思维导图]读深入理解JAVA内存模型整理的思维导图文章里面的思维导图或则相应的书籍.去看一遍. 能理解为什么并发编程就会出现故障. Java7并发编程实战手冊 ...

随机推荐

  1. (转)教你分分钟搞定Docker私有仓库Registry

    转:https://www.cnblogs.com/Javame/p/7389093.html 一.什么是Docker私有仓库Registry 官方的Docker hub是一个用于管理公共镜像的好地方 ...

  2. dubbo漫谈二

    转:腾信视频 阿甘 https://ke.qq.com/course/216518 https://blog.csdn.net/u013142781/article/details/50396621 ...

  3. Linux操作系统(三)_部署JDK

    一.通过tar.gz压缩包安装 1.在usr目录下创建java目录 cd usr mkdir java 2.用rz命令上传tar.gz安装包到java目录 3.解压tar.gz安装包到当前目录 tar ...

  4. JQuery获取与设置select

    获取select : 1.获取select 选中的 text :    $("#ddlregtype").find("option:selected").tex ...

  5. 基于全局地址池的DHCP

    一.实验目的 二.实验拓扑图 .三.实验编址 四.实验步骤 1.配置IP 2.配置基于全局地址池的DHCP server 使用IP pool命令创建一个新的全局地址池,名称为hjt1 配置hjt1可动 ...

  6. Cocos2d之FlyBird开发---简介

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 开发FlyBird其实非常的简单,在游戏的核心部分,我们需要实现的只有: 创建一个物理世界(世界设置重力加速度) 在物理世界中添加一个动态 ...

  7. C++中的临时对象

    1,临时对象神秘在于不知不觉就请入程序当中,并且给程序带来了一定的问题: 2,下面的程序输出什么?为什么? #include <stdio.h> class Test { int mi; ...

  8. MySQL Workbench无法显示左侧的navigator,只显示Object info和Session

    问题描述:Mac版MySQL Workbench出现异常强制退出后,再次进入后左侧的navigator消失,左侧整个导航条消失了,只显示Object info和Session. 问题根源:MySQL ...

  9. json模块 pickle 模块 collections 模块 openpyxl 模块

    json模块 json 模块是一个系列化模块 一个第三方的特殊数据格式 可以将python数据类型----> json 数据格式 ----> 字符串 ----> 文件 其他语言想要使 ...

  10. 52.Product of Array Except Self(除过自身的数组乘积)

    Level:   Medium 题目描述: Given an array nums of n integers where n > 1, return an array output such ...