当我们写一个单线程程序时,总以为计算机会一行行地运行代码,然而事实并非如此. 什么是重排序? 重排序指的是编译器.处理器在不改变程序执行结果的前提下,重新排列指令的执行顺序,以达到最佳的运行效率. 重排序分类 重排序分为:编译器重排序 和 处理器重排序. 数据依赖 编译器和处理器并不会随意的改变指令的执行顺序,因为有些指令之间是有依赖关系的,若改变了他们的执行顺序,就会出现错误的结果. 因此,编译器和处理器只会对没有依赖关系的指令进行重排序. 数据依赖:若相邻的两条指令访问同一个变量,并且其中有…
1. 并发编程的两个关键问题 并发是让多个线程同时执行,若线程之间是独立的,那并发实现起来很简单,各自执行各自的就行:但往往多条线程之间需要共享数据,此时在并发编程过程中就不可避免要考虑两个问题:通信 与 同步. 通信 通信是指消息在两条线程之间传递. 既然要传递消息,那接收线程 和 发送线程之间必须要有个先后关系,此时就需要用到同步.通信和同步是相辅相成的. 同步 同步是指,控制多条线程之间的执行次序. 2. 通信的方式 2.1 通信方式的种类 线程之间的通信一共有两种方式:共享内存 和 消息…
二.Java并发机制底层实现原理 这里是我的<Java并发编程的艺术>读书笔记的第二篇,对前文有兴趣的朋友可以去这里看第一篇:一.并发编程的目的与挑战 有兴趣讨论的朋友可以给我留言! 1.Volatile关键字 volatile的意义与定义 volatile和synchronized这两个关键字在并发编程中都扮演着极为重要的角色,这里我会先讨论volatile. volatile是轻量级的synchronized,它在开发中保证了共享变量的可见性和与其相关指令的有序性. 可见性就是指当某个共享…
离开博客园很久了,自从找到工作,到现在基本没有再写过博客了.在大学培养起来的写博客的习惯在慢慢的消失殆尽,感觉汗颜.所以现在要开始重新培养起这个习惯,定期写博客不仅是对自己学习知识的一种沉淀,更是在督促自己要不断的学习,不断的进步. 最近在进一步学习Java并发编程,不言而喻,这部分内容是很重要的.现在就以<并发编程的艺术>一书为主导线,开始新一轮的学习. 进程和线程 进程是一个应用程序在处理机上的一次执行过程,线程是进程的最小基本单位(个人理解).一个进程可以包含多个线程. 上下文切换 我们…
<Java并发编程实战>和<Java并发编程的艺术>           Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用程序要表现出良好的吞吐率和快速的响应性.在负载过载的情况下,应用程序的性能应该是逐渐减低的,而不是直接失败. 要实现高吞吐率和快速的响应,就应该选择清晰的任务边界和明确的任务执行策略. (2)任务执行策略有: 1)单线程串行执行任务:缺点:无法提高服务器应用程序的吞吐率和快速响应速度 2)根据任务显示创建线程…
接下来一个系列,是关于<Java并发编程的艺术>这本书的读书笔记以及相关知识点,主要是为了方便日后多次复习和防止忘记.废话不多说,直接步入主题: 第1章  并发编程的挑战 并发编程的目的是让程序运行得更快,但是并不是启动更多的线程就能让程序最大限度地并发执行.并发编程会遇到许多挑战,例如:上下文切换问题.死锁问题.以及受限于硬件和软件的资源限制问题. 1.1  上下文切换 进行上下文切换之前,会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载到这个状态.任务从保存到再加载的过程就是一…
一.多线程语义 即使是单核处理器也支持多线程执行代码,CPU 通过给每个线程分配 CPU 时间片来执行任务,当前任务执行一个时间片后会切换到下一个任务,所以 CPU 通过不停的切换线程执行. 并发执行如果没有达到一定的数量级,速度反而会比串行执行要慢.这是因为线程有创建和上下文切换的开销. 如何减少线程创建和上下文切换的开销?("vmstat 1" 的 cs 参数,查看线程切换的次数) 无锁并发编程.多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,比…
title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1.并发编程模型的两个关键问题 1.1线程之间如何通信. 通信是指线程之间以何种机制来交换信息.有两种:共享内存和消息传递.在共享内存的并发模型里,线程之间共享程序的公共状态,通过读写内存中的公共状态进行隐式通信.在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过发送消息来显示进行通信.j…
多条线程之间有时需要数据交互,下面介绍五种线程间数据交互的方式,他们的使用场景各有不同. 1. volatile.synchronized关键字 PS:关于volatile的详细介绍请移步至:Java并发编程的艺术(三)——volatile 1.1 如何实现通信? 这两种方式都采用了同步机制实现多条线程间的数据通信.与其说是“通信”,倒不如说是“共享变量”来的恰当.当一个共享变量被volatile修饰 或 被同步块包裹后,他们的读写操作都会直接操作共享内存,从而各个线程都能看到共享变量最新的值,…
<Java并发编程的艺术>这本书特别好,和<深入了解JAVA虚拟机>有一拼,建议做java的都看看,下面全部都是复制书中的部分内容,主要目的是做个笔记,方便以后遇到问题能找到. 在Java中,所有实例域.静态域和数组元素都存储在堆内存中,堆内存在线程之间共享.局部变量(Local Variables),方法定义参数(Java语言规范称之为Formal Method Parameters)和异常处理器参数(ExceptionHandler Parameters)不会在线程之间共享,它…
title: Java并发编程的艺术读书笔记(1)-并发编程的挑战 date: 2017-05-03 23:28:45 tags: ['多线程','并发'] categories: 读书笔记 --- 1.多线程不一定就比单线程快,因为线程有创建和上下文切换的开销. 1.1vmstat测试上下文切换次数,Lmbench3测时长 1.2如何减少上下文切换 1.2.1无锁并发编程:多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID取模分段,不同的线程处理…
本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cnblogs.com/wengshuhang/p/10200269.html 这两天在看<java并发编程的艺术>,记录下看到的知识当做笔记吧! java中的synchronized锁是存储在对象头中的,内容是mark word,长度根据计算机的位数来定32 or 64bit, 锁一共有4种状态,级…
[Java并发编程]之二:线程中断 使用interrupt()中断线程 ​ 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回.这里需要注意的是,如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行. ​ 下面一段代码演示了休眠线程的中断: public class SleepInterrupt extends Object implements Runna…
并发编程的优缺点 使用并发的原因 多核的CPU的背景下,催生了并发编程的趋势,通过并发编程的形式可以将多核CPU的计算能力发挥到极致,性能得到提升. 在特殊的业务场景下先天的就适合于并发编程. 比如在图像处理领域,一张1024X768像素的图片,包含达到78万6千多个像素.即时将所有的像素遍历一边都需要很长的时间, 面对如此复杂的计算量就需要充分利用多核的计算的能力.又比如当我们在网上购物时,为了提升响应速度,需要拆分,减库存, 生成订单等等这些操作,就可以进行拆分利用多线程的技术完成. 面对复…
模拟死锁 package com.gjjun.concurrent; /** * 模拟死锁,来源于<Java并发编程的艺术> * @Author gjjun * @Create 2018/8/12 **/ public class DeadLockDemo { private static String A = "A"; private static String B = "B"; public static void main(String[] arg…
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 一个图形化的工具,…
ConcurrentHashMap ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成. 一个ConcurrentHashMap里包含一个Segment数组,Segment的结构和HashMap类似,是一种数组和链表结构, 一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的元素, 每个Segment守护者一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segmen…
Java解决可见性和有序性问题:Java内存模型 什么是 Java 内存模型? Java 内存模型是个很复杂的规范,可以从不同的视角来解读,站在我们这些程序员的视角,本质上可以理解为, Java 内存模型规范了 JVM 如何提供按需禁用缓存和编译优化的方法.具体来说,这些方法包括 volatile.synchronized 和 final 三个关键字,以及六项 Happens-Before 规则. Happens-Before 规则:前一个操作的结果对后续操作可见. 前面一个操作的结果对后续操作…
发现自己有很多读书笔记了,但是一直都是自己闷头背,没有输出,突然想起还有博客圆这么个好平台给我留着位置,可不能荒废了. 此文读的书是<Jvava并发编程的艺术>,方腾飞等著,非常经典的一本书,本笔记是一边复习笔记,一边对照书本上的勾画重点,互相补充得来. 一.并发编程的目的与挑战 并发编程的目的只有一个:更充分的利用好计算资源,让程序运行的更快更有效率 请把这个目的牢记在心,因为,并不是启动更多的线程就能让程序最大限度的并发执行的,因为配合,甚至管理更多的线程本身也是有开销的.所以至少来说,利…
简单使用Lock锁 Java5中引入了新的锁机制--Java.util.concurrent.locks中的显式的互斥锁:Lock接口,它提供了比synchronized更加广泛的锁定操作.Lock接口有3个实现它的类:ReentrantLock.ReetrantReadWriteLock.ReadLock和ReetrantReadWriteLock.WriteLock,即重入锁.读锁和写锁.lock必须被显式地创建.锁定和释放,为了可以使用更多的功能,一般用ReentrantLock为其实例化…
第1章 并发编程的挑战 1.1 上下文切换 CPU通过时间片分配算法来循环执行任务,任务从保存到再加载的过程就是一次上下文切换. 减少上下文切换的方法有4种:无锁并发编程.CAS算法.使用最少线程.使用协程. 无锁并发编程:不同线程处理不同分片的数据,如数据哈希取模分片等. CAS算法:java的Atomic包使用cas算法更新数据,不需要加锁. 使用最少线程:任务少时避免创建不需要的线程,否则大量线程会等待状态. 使用协程:在单线程里实现多任务的调度.   1.2 死锁 避免死锁的几个常用方法…
在Java并发编程实践中4.4中提到向客户端加锁的方法.此为验证示例,写的不好,但可以看出结果来. package com.blackbread.test; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public…
第2章  Java并发机制的底层实现原理 Java代码在编译后变成字节码,字节码被类加载器加载到JVM中,JVM执行字节码,最终转换为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令. 2.1  volatile的应用 在并发编程中synchronized和volatile都具有重要的作用,volatile是轻量级的synchronized,保证了共享变量的可见性. 可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值. 如果volatil…
一.并发编程的挑战 1.上下文切换 (1)上下文切换的问题 在处理器上提供了强大的并行性就使得程序的并发成为了可能.处理器通过给不同的线程分配不同的时间片以实现线程执行的自动调度和切换,实现了程序并行的假象. 在单线程中:线程保存串行的执行,线程间的上下文切换不会造成很大的性能开销. 而在多线程中:线程之间频繁的调度需要进行上下文切换以保存当前执行线程的上下文信息和加载将要执行线程的上下文信息,而上下文切换时需要底层处理器.操作系统.Java虚拟机提供支持的会消耗很多的性能开 销.如果频繁的进行…
第一章  并发编程的挑战 需要了解的一些概念 转自 https://blog.csdn.net/TzBugs/article/details/80921351 (1) 同步VS异步 同步和异步通常用来形容一次方法调用.同步方法调用开始后,调用者必须等待被调用的方法结束后,调用者后面的代码才能执行.而异步调用,指的是,调用者不用管被调用方法是否完成,都会继续执行后面的代码,当被调用的方法完成后会通知调用者. (2) 并发与并行 并发和并行是十分容易混淆的概念.并发指的是多个任务交替进行,而并行则是…
Java并发机制的底层实现原理 1.volatile volatile相当于轻量级的synchronized,在并发编程中保证数据的可见性,使用 valotile 修饰的变量,其内存模型会增加一个 Lock 前缀,而这个前缀在多核处理器中带来的效果是: (1)会将处理器缓存行的数据回写到内存中: (2)同时这个操作会使其它处理器里缓存了这个内存地址的数据无效: 2.synchronized synchronized是重量级锁,其在JVM实现的原理是基于进入和退出 Monitor 对象来实现同步代…
Java内存模型 一.Java内存模型的基础 1.并发编程模型的两个关键问题: 两个关键问题,线程之间如何通信和如何同步.两种方式,共享内存和消息传递.Java里线程的通信是通过共享内存,线程的同步是显示进行的,而通信则是隐式进行的. 2.Java内存模型的抽象结构: 实际上就是说Java线程之间的通信是通过共享内存来进行交互. 3.从源代码到指令序列的重排序: 重排序,让指令序列重新排序而更高效地运行程序.Java中根据不同的处理器会禁用对应的重排序规则(内存屏障),从而保证了内存可见性. 4…
一.并发编程的挑战 上下文切换:cpu通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务.但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态.所以任务从保存到再加载的过程就是一次上下文切换. 如何减少上下文切换: 无锁并发编程 cas算法 使用最少线程 协程 避免死锁: 避免一个线程同时获取多个锁 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源 尝试使用定时锁,使用lock.tryLock(timeout)来替代使…
Java内存模型 并发编程的两个关键问题: 1.线程之间如何通讯. 2.线程间如何同步. 两种方式:共享内存和消息传递. Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式进行,整个通信过程对程序员完全透明. 实例域.静态域和数组元素都存储在堆内存中,堆内存在线程之间共享.Java线程之间的通信由Java内存模型:JMM控制. JMM通过控制主内存与每个线程的本地内存之间的交互,来为Java程序员提供内存可见性保证 . 重排序分3种类型: 1)编译器优化的重排序.编译器在不改变单…
1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递.   2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透明的.   3. 同步原语 有三个同步原语:Synchronized.volatile和final. Synchronized 的主要的含义是对指定的对象.方法.类 进行加锁和解锁的操作.保证当前只有一个线程进行访问. Volatile 的主要的含义是对指定的变量在数据的读取和更新时都从共享内存中进…