并发编程
Lucare
风能吹走纸张却吹不走蝴蝶,生命的力量在于不顺从!
展开
-
Executor框架
服务器应用中,串行处理机制通常无法提供高吞吐率或快速响应性。通过为每个请求创建一个新的线程来提供服务,从而实现更高的响应性。原创 2017-03-21 18:42:40 · 346 阅读 · 0 评论 -
volatile 和锁的内存语义
一、volatile 的内存语义1. volatile 的特性volatile变量自身具有以下特性:可见性 :对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写 入。原子性 :对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。2. volatile 写-读建立的happens-befo...原创 2018-06-30 17:36:54 · 334 阅读 · 0 评论 -
happens-before
happens-before 是JMM最核心的概念。对应Java程序员来说,理解happens-before是理解JMM的关键。一、JMM 的设计从JMM设计者的角度,在设计JMM时,需要考虑两个关键因素:程序员对内存模型的使用。程序员希望内存模型易于理解、易于编程。程序员希望基于一个强内存模型来编写代码。编译器和处理器对内存模型的实现。编译器和处理器希望内存模型对它们的束...原创 2018-07-10 09:23:30 · 1667 阅读 · 0 评论 -
双重检查锁定与延迟初始化
双重检查锁定的由来在Java程序中,有时候可能需要推迟一些高开销的对象初始化操作,并且只有在使用这些对象时才进行初始化。此时,程序员可能会采用延迟初始化。下面是非线程安全的延迟初始化:public class UnsafeLazyInitialization { private static Instance instance; public static Instan...原创 2018-07-23 20:43:10 · 367 阅读 · 0 评论 -
单元测试多线程解决之道
遇到问题曾今在开发的过程遇到一个问题,当时有一个服务是群发邮件的,由于一次发送几十个上百个,所以就使用了多线程来操作。在单元测试的时候,我调了这个方法测试下邮件发送,结果总是出现莫名其妙的问题,每次都没有全部发送成功。后来我感觉到启动的子线程都被杀掉了,好像测试方法一走完就over了,试着在测试方法末尾让线程睡眠个几秒,结果就能正常发送邮件。分析解决感觉这个Junit有点猫...原创 2018-07-15 20:56:47 · 6855 阅读 · 1 评论 -
队列同步器--AbstractQueuedSynchronizer
队列同步器队列同步器 AbstractQueuedSynchronizer(以下简称同步器),是用来构建锁或者其他同步组件的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。同步器的主要使用方式是继承,子类通过继承同步器并实现它的抽象方法来管理同步状态。同步器是实现锁(也可以是任意同步组件)的关键,在锁的实现中聚合同步器,利用同步器实现锁的...原创 2018-10-22 09:32:31 · 329 阅读 · 0 评论 -
Locksupport 与 Condition
LockSupportLockSupport定义了一组的公共静态方法,这些方法提供了最基本的线程阻塞和唤醒功能,而LockSupport也成为构建同步组件的基础工具。LockSupport定义了一组以park开头的方法用来阻塞当前线程,以及unpark(Thread thread)方法来唤醒一个被阻塞的线程。Park有停车的意思,假设线程为车辆,那么park方法代表着停车,而unpark...原创 2018-10-30 20:07:06 · 3738 阅读 · 0 评论 -
阻塞队列
什么是阻塞队列阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移除方法。1)支持阻塞的插入方法:意思是当队列满时,队列会阻塞插入元素的线程,直到队列不满。2)支持阻塞的移除方法:意思是在队列为空时,获取元素的线程会等待队列变为非空。阻塞队列常用于生产者和消费者的场景,生产者是向队列里添加元素的线程,消费者是从队列里取元素的线程...原创 2018-11-03 09:18:01 · 256 阅读 · 0 评论 -
线程池 -- ThreadPoolExecutor
线程池的实现原理1)如果当前运行的线程少于corePoolSize,则创建新线程来执行任务(注意,执行这一步骤需要获取全局锁)。2)如果运行的线程等于或多于corePoolSize,则将任务加入BlockingQueue。3)如果无法将任务加入BlockingQueue(队列已满),则创建新的线程来处理任务(注意,执行这一步骤需要获取全局锁)。4)如果创建新线程将使当前运行的线程超...原创 2018-11-25 14:47:14 · 539 阅读 · 0 评论 -
重排序
重排序 重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。1. 数据依赖性如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性。编译器和处理器在重排序时,会遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。这里所说的数据依赖性仅针对单个处理器中执行的指令序列和单个线程中执行的操...原创 2018-06-30 16:38:53 · 1382 阅读 · 0 评论 -
携带结果的任务 Callable 与 Future
Executor框架使用Runnable作为其基本任务表示形式。Runnable是一种有很大局限的抽象,它不能返回一个值或者抛出一个受检查的异常。但是许多任务实际上都是存在延迟的计算,比如执行数据库查询,从网络上获取资源,或者计算某个复杂的功能。对于这些任务,就要Callable来显身手了。原创 2017-03-26 20:08:08 · 405 阅读 · 0 评论 -
并发容器
ConcurrentHashMap使用一种粒度更细的加锁机制来实现更大程度的共享,这种机制称为分段锁。在这种机制中,任意数量的读取线程可以并发地访问Map,执行读取操作的线程和执行写入操作的线程可以并发地访问Map,并且一定数量的写入线程可以并发地修改Map。其带来的结果是,在并发访问的环境下将实现更高的吞吐量,而在单线程环境中只损失非常小的性能。原创 2017-04-04 20:41:38 · 319 阅读 · 0 评论 -
同步工具类
同步工具类可以是任何一个对象,只要它根据其自身的状态来协调线程的控制流。阻塞队列保存对象的容器, 还能协调生产者和消费者等线程之间的控制流 take和put等方法将阻塞,直到队列达到期望的状态(队列即非空,也非满)。原创 2017-06-24 22:37:39 · 364 阅读 · 0 评论 -
取消与关闭
任务取消中断线程中断是一种协作机制,线程可以通过这种机制来通知另一个线程,告诉它在合适的或者可能的情况下停止当前工作,并转而执行其他的工作。原创 2017-06-25 21:13:29 · 515 阅读 · 0 评论 -
线程安全与锁优化
线程安全的实现方法非阻塞同步互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能问题,因此这种同步也成为阻塞同步。随着硬件指令集的发展,我们有了另外一个选择:基于冲突检测的乐观并发策略原创 2017-07-16 22:50:20 · 286 阅读 · 0 评论 -
Synchronized 关键字
Java中的每一个对象都可以作为锁,具体表现为以下3种形式:对于普通同步方法,锁是当前实例对象对于静态同步方法,锁是当前类的Class对象对于同步代码块,锁是Synchronized括号里配置的对象synchronized作用于四种类型: 1. 实例方法 2. 静态方法 3. 实例方法中的同步块 4. 静态方法中的同步块同步方法实例同步方法publi...原创 2017-07-09 23:35:10 · 787 阅读 · 0 评论 -
Java内存模型
主内存与工作内存Java内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。内存间交互操作一个变量如何从主内存拷贝到工作内存,如何从工作内存同步回主内存?原创 2017-06-11 22:48:11 · 253 阅读 · 0 评论 -
Java 内存模型基础
并发编程模型的两个关键问题线程之间如何通信通信是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递。在共享内存的并发模型里,线程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通信。在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过发送消息来显式进行通信。线程之间如何同步同步是指程序中用于控制不同线程间...原创 2018-06-24 11:52:21 · 216 阅读 · 0 评论 -
异步任务 -- FutureTask
任务提交之前在分析线程池的时候,提到过 AbstractExecutorService 的实现:public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskF...原创 2019-01-24 21:00:18 · 877 阅读 · 0 评论