![](https://img-blog.csdnimg.cn/20201014180756724.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
并发
文章平均质量分 89
∝ 1 颗心╮
Java
展开
-
Treiber Stack简单分析
AbstractTreiber Stack Algorithm是一个可扩展的无锁栈,利用细粒度的并发原语CAS来实现的,Treiber Stack在 R. Kent Treiber在1986年的论文Systems Programming: Coping with Parallelism中首次出现。基本原理该算法的基本原理是:只有当您知道要添加的项目是自开始操作以来唯一添加的项目时,才会...转载 2020-03-07 11:23:53 · 137 阅读 · 0 评论 -
FutureTask源码解析(1)——预备知识
FutureTask 是一个同步工具类,它实现了Future语义,表示了一种抽象的可生成结果的计算。在包括线程池在内的许多工具类中都会用到,弄懂它的实现将有利于我们更加深入地理解Java异步操作实现。在分析它的源码之前, 我们需要先了解一些预备知识。本篇我们先来看看FutureTask 中所使用到的接口:Runnable、Callable、Future、RunnableFuture以及所使用到...转载 2020-03-07 11:19:09 · 127 阅读 · 0 评论 -
FutureTask源码解析(2)——深入理解FutureTask
Future和Task在深入分析源码之前,我们再来拎一下FutureTask到底是干嘛的。人如其名,FutureTask包含了Future和Task两部分。FutureTask实现了RunnableFuture接口,即Runnable接口和Future接口。其中Runnable接口对应了FutureTask名字中的Task,代表FutureTask本质上也是表征了一个任务。而Future接...转载 2020-03-07 11:09:10 · 480 阅读 · 0 评论 -
Java并发编程的艺术(九)——彻底理解ReentrantLock
1. ReentrantLock的介绍ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,支持重入性,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。在java关键字synchronized隐式支持重入性,synchronized通过获取自增,释放自减的方式实现重入。与此同时,ReentrantLock还支持公平锁和非公平锁...转载 2019-06-01 10:51:16 · 107 阅读 · 0 评论 -
Java并发编程的艺术(十)——深入理解读写锁ReentrantReadWriteLock
1.读写锁的介绍在并发场景中用于解决线程安全的问题,我们几乎会高频率的使用到独占式锁,通常使用java提供的关键字synchronized或者concurrents包中实现了Lock接口的ReentrantLock。它们都是独占式获取锁,也就是在同一时刻只有一个线程能够获取锁。而在一些业务场景中,大部分只是读数据,写数据很少,如果仅仅是读数据的话并不会影响数据正确性(出现脏读),而如果在这种业...转载 2019-06-01 11:06:56 · 131 阅读 · 0 评论 -
Java并发编程的艺术(十一)——详解Condition的await和signal等待/通知机制
1.Condition简介任何一个java对象都天然继承于Object类,在线程间实现通信的往往会应用到Object的几个方法,比如wait(),wait(long timeout),wait(long timeout, int nanos)与notify(),notifyAll()几个方法实现等待/通知机制,同样的, 在java Lock体系下依然会有同样的方法实现等待/通知机制。从整体上来...转载 2019-06-01 11:11:14 · 149 阅读 · 0 评论 -
Java并发编程的艺术(十二)——LockSupport工具
1. LockSupport简介在之前介绍AQS的底层实现,已经在介绍java中的Lock时,比如ReentrantLock,ReentReadWriteLocks,已经在介绍线程间等待/通知机制使用的Condition时都会调用LockSupport.park()方法和LockSupport.unpark()方法。而这个在同步组件的实现中被频繁使用的LockSupport到底是何方神圣,现在...转载 2019-06-01 11:12:57 · 130 阅读 · 0 评论 -
Java并发编程的艺术(二十)——线程池ThreadPoolExecutor实现原理
1. 为什么要使用线程池在实际使用中,线程是很占用系统资源的,如果对线程管理不善很容易导致系统问题。因此,在大多数并发框架中都会使用线程池来管理线程,使用线程池管理线程主要有如下好处:降低资源消耗。通过复用已存在的线程和降低线程关闭的次数来尽可能降低系统性能损耗; 提升系统响应速度。通过复用线程,省去创建线程的过程,因此整体上提升了系统的响应速度; 提高线程的可管理性。线程是稀缺资源,...转载 2019-06-13 13:35:46 · 116 阅读 · 0 评论 -
Java并发编程的艺术(十三)——并发容器之ConcurrentHashMap(JDK 1.8版本)
1.ConcurrentHashmap简介在使用HashMap时在多线程情况下扩容会出现CPU接近100%的情况,因为hashmap并不是线程安全的,通常我们可以使用在java体系中古老的hashtable类,该类基本上所有的方法都采用synchronized进行线程安全的控制,可想而知,在高并发的情况下,每次只有一个线程能够获取对象监视器锁,这样的并发性能的确不令人满意。另外一种方式通过Co...转载 2019-06-02 09:38:21 · 255 阅读 · 0 评论 -
Java并发编程的艺术(十四)——并发容器之CopyOnWriteArrayList
1. CopyOnWriteArrayList的简介java学习者都清楚ArrayList并不是线程安全的,在读线程在读取ArrayList的时候如果有写线程在写数据的时候,基于fast-fail机制,会抛出ConcurrentModificationException异常,也就是说ArrayList并不是一个线程安全的容器,当然您可以用Vector,或者使用Collections的静态方法将...转载 2019-06-02 09:43:47 · 125 阅读 · 0 评论 -
Java并发编程的艺术(十五)——并发容器之ConcurrentLinkedQueue
1.ConcurrentLinkedQueue简介在单线程编程中我们会经常用到一些集合类,比如ArrayList,HashMap等,但是这些类都不是线程安全的类。在面试中也经常会有一些考点,比如ArrayList不是线程安全的,Vector是线程安全。而保障Vector线程安全的方式,是非常粗暴的在方法上用synchronized独占锁,将多线程执行变成串行化。要想将ArrayList变成线程...转载 2019-06-02 09:49:18 · 157 阅读 · 0 评论 -
Java并发编程的艺术(十六)——并发容器之ThreadLocal
1. ThreadLocal的简介在多线程编程中通常解决线程安全的问题我们会利用synchronzed或者lock控制线程对临界区资源的同步顺序从而解决线程安全的问题,但是这种加锁的方式会让未获取到锁的线程进行阻塞等待,很显然这种方式的时间效率并不是很好。线程安全问题的核心在于多个线程会对同一个临界区共享资源进行操作,那么,如果每个线程都使用自己的“共享资源”,各自使用各自的,又互相不影响到彼...转载 2019-06-02 09:51:43 · 117 阅读 · 0 评论 -
Java并发编程的艺术(十七)——一篇文章,从源码深入详解ThreadLocal内存泄漏问题
1. 造成内存泄漏的原因?转载 2019-06-02 09:52:25 · 112 阅读 · 0 评论 -
Java并发编程的艺术(十八)——并发容器之BlockingQueue
1. BlockingQueue简介在实际编程中,会经常使用到JDK中Collection集合框架中的各种容器类如实现List,Map,Queue接口的容器类,但是这些容器类基本上不是线程安全的,除了使用Collections可以将其转换为线程安全的容器,Doug Lea大师为我们都准备了对应的线程安全的容器,如实现List接口的CopyOnWriteArrayList,实现Map接口的Con...转载 2019-06-02 09:54:52 · 103 阅读 · 0 评论 -
Java并发编程的艺术(十九)——并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解
1. ArrayBlockingQueue简介在多线程编程过程中,为了业务解耦和架构设计,经常会使用并发容器用于存储多线程间的共享数据,这样不仅可以保证线程安全,还可以简化各个线程操作。例如在“生产者-消费者”问题中,会使用阻塞队列(BlockingQueue)作为数据容器,关于BlockingQueue可以看前面的文章。为了加深对阻塞队列的理解,唯一的方式是对其实验原理进行理解,这篇文章就主...转载 2019-06-02 09:57:47 · 107 阅读 · 0 评论 -
Java并发编程的艺术(九)——深入理解AbstractQueuedSynchronizer(AQS)
1. AQS简介在上一篇文章中我们对lock和AbstractQueuedSynchronizer(AQS)有了初步的认识。在同步组件的实现中,AQS是核心部分,同步组件的实现者通过使用AQS提供的模板方法实现同步组件语义,AQS则实现了对同步状态的管理,以及对阻塞线程进行排队,等待通知等等一些底层的实现处理。AQS的核心也包括了这些方面:同步队列,独占式锁的获取和释放,共享锁的获取和释放以及...转载 2019-06-01 09:35:40 · 113 阅读 · 0 评论 -
Java并发编程的艺术(八)——初识Lock与AbstractQueuedSynchronizer(AQS)
1. concurrent包的结构层次在针对并发编程中,Doug Lea大师为我们提供了大量实用,高性能的工具类,针对这些代码进行研究会让我们队并发编程的掌握更加透彻也会大大提升我们对并发编程技术的热爱。这些代码在java.util.concurrent包下。如下图,即为concurrent包的目录结构图。其中包含了两个子包:atomic以及lock,另外在concurrent下的阻塞...转载 2019-06-01 09:01:14 · 128 阅读 · 0 评论 -
Java并发编程:Synchronized及其实现原理
Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。Synchronized的作用主要有三个:(1)确保线程互斥的访问同步代码(2)保证共享变量的修改能够及时可见(3)有效解决重排序问题。从语法上讲,Synchronized总共有三种用法:同步普通方法,锁的是当前对象。 同步静态方法,锁的是当前Class对象。 同步块,锁的是()中的对象。...转载 2019-05-21 20:27:56 · 135 阅读 · 0 评论 -
Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)
线程的状态 Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态)。 New:新建状态,当线程创建完成时为新建状态,即new Thread(...),还没有调用start方法时,线程处于新建状态。 Runnable:就绪状态,当调用线程的的start方法后,线程进入就绪状态,...转载 2019-05-21 20:45:30 · 349 阅读 · 0 评论 -
Java 并发编程:volatile的使用及其原理
一、volatile的作用我们已经提到过可见性、有序性及原子性问题,通常情况下我们可以通过Synchronized关键字来解决这些个问题,不过如果对Synchronized原理有了解的话,应该知道Synchronized是一个比较重量级的操作,对系统的性能有比较大的影响,所以,如果有其他解决方案,我们通常都避免使用Synchronized来解决问题。而volatile关键字就是Java中提供的...转载 2019-05-21 21:09:24 · 111 阅读 · 0 评论 -
深入理解线程通信
前言开发中不免会遇到需要所有子线程执行完毕通知主线程处理某些逻辑的场景。或者是线程 A 在执行到某个条件通知线程 B 执行某个操作。可以通过以下几种方式实现:等待通知机制等待通知模式是 Java 中比较经典的线程通信方式。两个线程通过对同一对象调用等待 wait() 和通知 notify() 方法来进行通讯。如两个线程交替打印奇偶数:public class ...转载 2019-05-21 21:19:30 · 74 阅读 · 0 评论 -
Java技术之AQS详解
一、概述AQS是AbustactQueuedSynchronizer的简称,是用来构建锁或者其他同步组件的基础框架,它使用一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取的排队工作。许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch...。二、框架 它维护了一个volatile int state(...转载 2019-05-21 22:10:03 · 277 阅读 · 0 评论 -
Java并发编程的艺术(一)——并发编程需要注意的问题
并发是为了提升程序的执行速度,但并不是多线程一定比单线程高效,而且并发编程容易出错。若要实现正确且高效的并发,就要在开发过程中时刻注意以下三个问题:上下文切换 死锁 资源限制问题一:上下文切换会带来额外的开销线程的运行机制一个CPU每个时刻只能执行一条线程; 操作系统给每条线程分配不同长度的时间片; 操作系统会从一堆线程中随机选取一条来执行; 每条线程用完自己的时间片后,即...转载 2019-05-31 08:31:56 · 79 阅读 · 0 评论 -
《Java并发编程的艺术》笔记
第二章 Java并发机制的底层实现原理volatile的两条实现原则:Lock前缀指令会引起处理器缓存回写到内存 一个处理器的缓存回写到内存会导致其他处理器的缓存无效。volatile的使用优化:共享变量会被频繁读写时,可以通过追加为64字节以提高并发编程的效率。因为目前主流处理器高速缓存行是64个字节宽,不支持部分填充缓存行,通过追加到64字节的方式填满高速缓冲区的缓存行,避免各元素...转载 2019-05-31 08:55:58 · 102 阅读 · 0 评论 -
Java并发编程的艺术(二)——线程的状态转换以及基本操作
1. 新建线程一个java程序从main()方法开始执行,然后按照既定的代码逻辑执行,看似没有其他线程参与,但实际上java程序天生就是一个多线程程序,包含了:(1)分发处理发送给给JVM信号的线程;(2)调用对象的finalize方法的线程;(3)清除Reference的线程;(4)main线程,用户程序的入口。那么,如何在用户程序中新建一个线程了,只要有三种方式:1. 通过继承Thre...转载 2019-05-31 09:37:47 · 130 阅读 · 0 评论 -
Java并发编程的艺术(三)——Java内存模型以及happens-before规则
1. JMM的介绍在多线程中稍微不注意就会出现线程安全问题,那么什么是线程安全问题?我的认识是,在多线程下代码执行的结果与预期正确的结果不一致,该代码就是线程不安全的,否则则是线程安全的。虽然这种回答似乎不能获取什么内容,可以google下。在<<深入理解Java虚拟机>>中看到的定义。原文如下:当多个线程访问同一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替...转载 2019-05-31 09:43:26 · 124 阅读 · 0 评论 -
Java并发编程的艺术(四)——彻底理解synchronized
1. synchronized简介我们已经知道出现线程安全的主要来源于JMM的设计,主要集中在主内存和线程的工作内存而导致的内存可见性问题,以及重排序导致的问题,进一步知道了happens-before规则。线程运行时拥有自己的栈空间,会在自己的栈空间运行,如果多线程间没有共享的数据也就是说多线程间并没有协作完成一件事情,那么,多线程就不能发挥优势,不能带来巨大的价值。那么共享数据的线程安全问...转载 2019-05-31 09:51:15 · 145 阅读 · 0 评论 -
Java并发编程的艺术(五)——彻底理解volatile
1. volatile简介在上一篇文章中我们深入理解了java关键字,我们知道在java中还有一大神器就是关键volatile,可以说是和synchronized各领风骚,其中奥妙,我们来共同探讨下。通过上一篇的文章我们了解到synchronized是阻塞式同步,在线程竞争激烈的情况下会升级为重量级锁。而volatile就可以说是java虚拟机提供的最轻量级的同步机制。但它同时不容易被正确...转载 2019-05-31 09:58:51 · 185 阅读 · 0 评论 -
Java并发编程的艺术(六)——你以为你真的了解final吗?
1. final的简介final可以修饰变量,方法和类,用于表示所修饰的内容一旦赋值之后就不会再被改变,比如String类就是一个final类型的类。即使能够知道final具体的使用方法,我想对final在多线程中存在的重排序问题也很容易忽略,希望能够一起做下探讨。2. final的具体使用场景final能够修饰变量,方法和类,也就是final使用范围基本涵盖了java每个地方,下面就...转载 2019-05-31 10:20:09 · 129 阅读 · 0 评论 -
Java并发编程的艺术(七)——三大性质总结:原子性、可见性以及有序性
1. 三大性质简介在并发编程中分析线程安全的问题时往往需要切入点,那就是两大核心:JMM抽象内存模型以及happens-before规则,三条性质:原子性,有序性和可见性。关于synchronized和volatile已经讨论过了,就想着将并发编程中这两大神器在 原子性,有序性和可见性上做一个比较,当然这也是面试中的高频考点,值得注意。2. 原子性原子性是指一个操作是不可中断的,要么全...转载 2019-05-31 10:25:44 · 165 阅读 · 0 评论 -
Java并发编程:核心理论
一、共享性数据共享性是线程安全的主要原因之一。如果所有的数据只是在线程内有效,那就不存在线程安全性问题,这也是我们在编程的时候经常不需要考虑线程安全的主要原因之一。但是,在多线程编程中,数据共享是不可避免的。最典型的场景是数据库中的数据,为了保证数据的一致性,我们通常需要共享同一个数据库中数据,即使是在主从的情况下,访问的也同一份数据,主从只是为了访问的效率和数据安全,而对同一份数据做的副本。...转载 2019-05-21 19:45:42 · 91 阅读 · 0 评论