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. JetBrains CLion

    JetBrains CLion 2017.2.4 ①.激活时选择License server: http://idea.irfen.me/ http://idea.imsxm.com/

  2. mac使用相关笔记

    1.软件提示已损坏,需要移到废纸篓的解决方法 -> sudo spctl --master-disable xattr -r -d com.apple.quarantine <path&g ...

  3. CentOS 7在VMware 12中共享文件看不见的问题?

    前言 由于rhel 7.2因为没有注册导致yum无法使用,包括自己配置本地源,这个命令在你没有注册都不能使用,每次使用rpm去装软件,自己去找缺少的依赖包,实在是麻烦.于是不如就换一个系统,CentO ...

  4. pod 查看当前源/添加源

    1 pod 查看当前源 PeiSongs-iMac:5i5jAPP chenpeisong$ pod repo 0 repos 2 pod repo换源 CocoaPods 镜像使用帮助CocoaPo ...

  5. upc组队赛14 Communication【并查集+floyd /Tarjan】

    Communication 题目描述 The Ministry of Communication has an extremely wonderful message system, designed ...

  6. linux下用户切换

    Linux学习使用ubuntu17,ubuntu安装的时候没有超级用户root的密码. 设置系统root用户的密码,Ubuntu刚安装后,因为root没有默认密码,需要手动设定.以安装ubuntu时输 ...

  7. Java必备主流技术流程图,写得非常好!

    作者:Jay_huaxiao https://juejin.im/post/5d214639e51d4550bf1ae8df 1.spring的生命周期 Spring作为当前Java最流行.最强大的轻 ...

  8. java树的遍历

    java二叉树的遍历算法: http://blog.sina.com.cn/s/blog_70600f720100ujnp.html

  9. python3 tkinter模块小项目联系之邮箱客户端

    # -*- coding:utf-8 -*- from tkinter import * from tkinter.messagebox import askyesno, showerror, sho ...

  10. SQL数据库— <3>高级查询、常用函数 --摘录网络

    SQL Server T-SQL高级查询 高级查询在数据库中用得是最频繁的,也是应用最广泛的. Ø 基本常用查询 --select select * from student; --all 查询所有 ...