Java并发读书笔记:JMM与重排序】的更多相关文章

目录 导致线程不安全的原因 什么是线程安全 不可变 绝对线程安全 相对线程安全 线程兼容 线程对立 互斥同步实现线程安全 synchronized内置锁 锁即对象 是否要释放锁 实现原理 啥是重进入? ReentrantLock(重入锁) API层面的互斥锁 等待可中断 公平锁 锁绑定 本篇参考许多著名的书籍,形成读书笔记,便于加深记忆. 前文传送门:Java并发读书笔记:JMM与重排序 导致线程不安全的原因 当一个变量被多个线程读取,且至少被一个线程写入时,如果读写操作不遵循happens-b…
目录 Java内存模型(JMM) JMM抽象结构 重排序 源码->最终指令序列 编译器重排序 处理器重排序 数据依赖性 as-if-serial happens-before happens-before的规则 happens-before关系的定义 重排序对多线程的影响 顺序一致性 数据竞争与顺序的一致性 顺序一致性内存模型 总结 JMM遵循的基本原则: as-if-serial与happens-before的异同 Java内存模型(JMM) Java内存模型(JMM)定义了程序中各个变量的访…
在执行程序时为了提高性能,提高并行度,编译器和处理器常常会对指令做重排序.重排序分三种类型: 编译器优化的重排序.编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序. 指令级并行的重排序.现代处理器采用了指令级并行技术(Instruction-Level Parallelism, ILP)来将多条指令重叠执行.如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序. 内存系统的重排序.由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行. 问题:重排…
一.happns-before happns-before是学习指令重排序前的一个必须了解的知识点,他的作用主要是就是用来判断代码的执行顺序. 1.定义 happens-before是用来指定两个操作之间的执行顺序.提供跨线程的内存可见性. 在java内存模型中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必然存在happens-before关系 2.happens-before规则 a.程序顺序规则 单线程中的每个操作,总是前一个操作happens-before于该线程中的任…
Lock位于java.util.concurrent.locks包下,是一种线程同步机制,就像synchronized块一样.但是,Lock比synchronized块更灵活.更复杂. 话不多说,我们直接来看官方文档对Lock接口相关概念及功能的描述,今天又是看英文文档,翻译理解的一天. 一.Lock继承关系 二.官方文档解读 三.Lock接口方法解读 void lock() 获取锁.如果锁不可用,则当前线程将出于线程调度目的而禁用,并处于休眠状态,直到获得锁为止. void lockInter…
当我们写一个单线程程序时,总以为计算机会一行行地运行代码,然而事实并非如此. 什么是重排序? 重排序指的是编译器.处理器在不改变程序执行结果的前提下,重新排列指令的执行顺序,以达到最佳的运行效率. 重排序分类 重排序分为:编译器重排序 和 处理器重排序. 数据依赖 编译器和处理器并不会随意的改变指令的执行顺序,因为有些指令之间是有依赖关系的,若改变了他们的执行顺序,就会出现错误的结果. 因此,编译器和处理器只会对没有依赖关系的指令进行重排序. 数据依赖:若相邻的两条指令访问同一个变量,并且其中有…
目录 一.synchronized 与 volatile 二.等待/通知机制 等待 通知 面试常问的几个问题 sleep方法和wait方法的区别 关于放弃对象监视器 三.等待通知典型 生产者消费者模型 可能会出错的代码 四.使用显式的Lock和Condition Condition接口内的方法详解 Condition与Lock配合 Condition接口与Object监视器 五.管道输入.输出流 六.Thread.join() 七.利用ThreadLocal 在并发编程中,保证线程同步,从而实现…
目录 synchronized 与 volatile 等待/通知机制 等待 通知 面试常问的几个问题 sleep方法和wait方法的区别 关于放弃对象监视器 在并发编程中,保证线程同步,从而实现线程之间正确通信,是一个值得考虑的问题.本篇将参考许多著名书籍,学习如何让多个线程之间相互配合,完成我们指定的任务. 当然本文只是学习了一部分线程间通信的方法,还有一些例如使用Lock和Condition对象,管道输入输出.生产者消费者等内容,我们之后再做学习. synchronized 与 volati…
<深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考<Java并发编程的艺术> 关于线程安全和线程安全的程度参考了<Java并发编程实战> 图片参考https://www.processon.com/u/5dee0443e4b093b9f775065c#pc 一丶Java内存模型 1.概述 多任务处理已经是操作系统的必备技能,计算机被要求…
java并发编程笔记(三)--线程安全性 线程安全性: ​ 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的. 线程安全体现在三个方面: 原子性:提供了互斥访问,同一时刻只能有一个线程来对它进行操作 可见性:一个线程对主内存的修改可以及时的被其他线程观察到 有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排序的存在,该观察结果一般杂乱无序. 原子性:Atom…
java并发编程笔记(四)--安全发布对象 发布对象 使一个对象能够被当前范围之外的代码所使用 对象逸出 一种错误的发布.当一个对象还没构造完成时,就使它被其他线程所见 不安全的发布对象 某一个类的构造方法为公共的. 如: public class UnsafePublish { private String[] states = {"a", "b", "c"}; public String[] getStates() { return stat…
java effective 读书笔记 []创建和销毁对象 静态工厂方法 就是“封装了底层 暴露出一个访问接口 ” 门面模式 多参数时 用构建器,就是用个内部类 再让内部类提供构造好的对象 枚举 singleton 不知道怎么操作,觉得意义不大 单例模式 私有化构造器不能实例化,也不可被子类继承 能用原生类的就尽量不用对象 []对于所有对象都通用的方法 reflexivity 自反性 symmetry 对称性 []类成员 降低可访问性 尽量把公有域 变成私有域,并提供 访问和修改的 get se…
java并发编程笔记(六)--AQS 使用了Node实现FIFO(first in first out)队列,可以用于构建锁或者其他同步装置的基础框架 利用了一个int类型表示状态 使用方法是继承 子类通过继承并通过实现它的方法管理其状态(acquire和release)的方法操纵状态 可以同时实现排它锁和共享锁模式(独占.共享) AQS同步组件 CountDownLatch Semaphore CyclicBarrier ReentrantLock Condition FutureTask C…
java并发编程笔记(五)--线程安全策略 不可变得对象 不可变对象需要满足的条件 对象创建以后其状态就不能修改 对象所有的域都是final类型 对象是正确创建的(在对象创建期间,this引用没有逸出) final关键字:类.方法.变量 修饰类:不能被继承 修饰方法:1.锁定方法不被继承类修改:2.效率,目前近期版本已经将私有方法默认设置为final,final能够使方法转为内嵌调用. 修饰变量:基本数据类型变量.引用类型变量 定义不可变对象的其他方法: Collections.unmodifi…
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 { ExecutorS…
读书笔记:<重来REWORK> <重来Rework--更为简单有效的商业思维>这本书是看了别人的书单而购买的,初 拿到这本书翻看时,感觉有两点与平常的书不同,一是每个小节非常短,通常是一页,最多二页,二是附有大量的插图,原以为这些插图可能是用来凑页数的,但细 看一些插图,虽然都是用手工画的,但却能用形象的办法表示出一小节的观点,很象是出自做软件原型的人员之手. 这本书包含了80多个观点,特别适合指导小型软件公司的创业,感觉对我做的软件项目也有帮助. 卸负篇TAKEDOWNS 忘了“…
深入理解Java虚拟机 -- 读书笔记:JVM运行时数据区域 本文转载:http://blog.csdn.net/jubincn/article/details/8607790 本系列为<深入理解Java虚拟机 >(周志明著)读书笔记. Java程序员一般都知道JVM中存在栈和堆的,并简单了解对象是在堆上分配的,这点从C/C++转过Java的程序员很容易想到.但Java由于其自身的特性,还有一些其他的内存区域,如下图所示: 程序计数器 程序计数器占用的内存空间不大,里面记录了各线程当前字节码的…
java并发编程笔记(十一)--高并发处理思路和手段 扩容 垂直扩容(纵向扩展):提高系统部件能力 水平扩容(横向扩容):增加更多系统成员来实现 缓存 缓存特征 命中率:命中数/(命中数+没有命中数) 一.影响因素 业务场景和业务需求 缓存的设计(粒度和策略) 缓存的容量和基础设施 二.缓存分类和应用场景 本地缓存:编程实现(成员变量,局部变量,静态变量).Guava Cache 分布式缓存:Memcache.Redis 三.常用组件 Guava Cache public class Guava…
java并发编程笔记(十)--HashMap与ConcurrentHashMap HashMap参数 有两个参数影响他的性能 初始容量(默认为16) 加载因子(默认是0.75) HashMap寻址方式 对一个我们需要插入的数据或者我们要读取的数据,首先hashMap会将它的key按照一定的计算规则计算出的hash值并对我们的数组长度进行取模,结果作为插入数组织位置的index. 在计算中,取模的代价远远高于位移的代价,因此hashMap要求数组的长度一定是2的n次方:此时它将key的hash值对…
java并发编程笔记(九)--多线程并发最佳实践 使用本地变量 使用不可变类 最小化锁的作用域范围 使用线程池Executor,而不是直接new Thread执行 宁可使用同步也不要使用线程的wait和notify 使用BlockingQueue实现生产-消费模式 使用并发集合而不是加了锁的同步集合(比如Collections.synchronized这些集合尽量避免使用,应该用J.U.C中提供的专门的同步集合) 使用Semaphore创建有界的访问 宁可使用同步代码块,也不要使用同步的方法 避…
java并发编程笔记(八)--死锁 死锁发生的必要条件 互斥条件 进程对分配到的资源进行排他性的使用,即在一段时间内只能由一个进程使用,如果有其他进程在请求,只能等待. 请求和保持条件 进程已经保持了至少一个资源,但是又提出了新的资源请求,而该资源又被其他进程占有,造成请求阻塞,但是又对自己已经占有的资源不放 不剥夺条件 是指进程在对已经占有的资源未使用完的情况下,不能被剥夺,只能在使用完时自己释放 环路等待条件 public class DeadLock implements Runnable…
java并发编程笔记(七)--线程池 new Thread弊端 每次new Thread新建对象,性能差 线程缺乏统一管理,可能无限制的新建线程,相互竞争,有可能占用过多系统资源导致死机或者OOM 缺少更多功能,如更多执行.定期执行.线程中断 线程池的好处 重用存在的线程,减少对象创建.消亡的开销,性能佳 可有效控制最大并发线程数,提高系统资源利用率,同时可以避免过多资源竞争,避免阻塞 提供定时执行.定期执行.单线程.并发数控制等功能 ThreadPoolExecutor 重要核心参数 core…
java并发编程笔记(二)--并发工具 工具: Postman:http请求模拟工具 Apache Bench(AB):Apache附带的工具,测试网站性能 JMeter:Apache组织开发的压力测试工具 代码:Semaphone.CountDownLatch等 PostMan: Apache Bench(AB) ab -n [请求总数] -c [本次请求的并发数是50] [url] 例如:ab -1000 -c 50 http://www.baidu.com JMeter 一个图形化的工具,…
单元测试知道Java版读书笔记 首先我们必须要知道我们所写的代码,它的功能是什么,如果我们不了解代码的行为,那么也就无从测试. 我们测试的目的,是为了我们整个程序架构的稳定,代码其实就是欧文要实现功能的底层基础,如果说前一步做错了,那么可能后面所做的都是无用功.所以好的单元测试能让我们缩短工作时间 通过编译只能代表你的语法和逻辑是正确的,但是不能代表你的程序能解决所有遇到的问题. 所谓的代码正确,是具有时效性的,它只能代表你在当前这个时间点能够满足用户的需求,但是客户的需求总是在变化的,所以我们…
什么是JMM JMM就是Java内存模型.目的是为了屏蔽系统和硬件的差异,让同一代码在不同平台下能够达到相同的访问结果.规定了线程和内存之间的关系. 内存划分 JMM规定了内存主要划分为主内存和工作内存. 如果Java线程都去操作主内存,对性能的影响就很大,如果每个线程都具有自己的工作内存,然后再将工作内存与主内存进行同步,就能提高性能. 这也会带来很多副作用,就是线程对内存的可见性问题,线程安全的问题. JMM与JVM区别 不用Java虚拟机的内存区域划分,是两种逻辑的存在,是不同层次的划分结…
1. 并发编程的3个概念 并发编程时,要想并发程序正确地执行,必须要保证原子性.可见性和有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.1. 原子性 原子性:即一个或多个操作要么全部执行并且执行过程中不会被打断,要么都不执行. 一个经典的例子就是银行转账:从账户A向账户B转账1000元,此时包含两个操作:账户A减去1000元,账户B加上1000元.这两个操作必须具备原子性才能保证转账安全.假如账户A减去1000元之后,操作被打断了,账户B却没有收到转过来的1000元,此时就出问…
目录 计算机系统的一致性 Java内存模型 内存模型的3个重要特征 原子性 可见性 有序性 指令重排序 volatile关键字 保证可见性和防止指令重排 不能保证原子性 计算机系统的一致性 在现代计算机操作系统中,多任务处理几乎是一项必备的功能,因为嵌入了多核处理器,计算机系统真正做到了同一时间执行若干个任务,是名副其实的多核系统.在多核系统中,为了提升CPU与内存的交互效率,一般都设置了一层 "高速缓存区" 作为内存与处理器之间的缓冲,使得CPU在运算的过程中直接从高速缓存区读取数据…
底层的并发功能与并发语义不存在一一对应的关系.同步和条件等底层机制在实现应用层协议与策略须始终保持一致.(需要设计级别策略.----底层机制与设计级策略不一致问题). 简介 1.并发简史.(资源利用率/公平性/便利性),进程通信通过粗粒度通信机制:文件/套接字/信号量/信号处理器/共享内存.高效做事----串行和异步好的平衡. 线程共享文件句柄和内存句柄,都有自己的程序计数器.栈.局部变量:都访问堆中内存,需要更细粒度的内存共享机制. 2.线程优势 降低程序开发维护成本,提升性能(将异步工作流转…
八 Java内存模型与线程   1 Java内存模型     ---主要目标:定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节.     ---此处的变量和Java中的变量有所区别,它包括类字段.实例字段和构成数组对象的元素,但不包括局部变量和方法参数.     ---Java内存模型规定:         · 所有的变量都存储在主内存中:         · 每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副拷贝,线程对变…
题记: 花了一周把Peter Haggar的<practical Java>看了遍,有所感悟,年纪大了, 写下笔记,方便日后查看.也希望有缘之人可以看看,做个渺小的指路人. 不足之处还望指正. 概述: 全书分为六个部分,包括一般技术.对象与相等性.异常处理.性能.多线程.对象. 一般技术:举例了几个java常见错误用法的说明和解释,诸如array和vector的选择,多态与instanceof等等 对象和相等性则:针对equals的详细说明,是迄今本人见过对equals理解最深的一本书了,其中…