和朱晔一起复习Java并发(二):队列 老样子,我们还是从一些例子开始慢慢熟悉各种并发队列.以看小说看故事的心态来学习不会显得那么枯燥而且更容易记忆深刻. 阻塞队列的等待? 阻塞队列最适合做的事情就是做为生产消费者的中间存储,以抵抗生产者消费者速率不匹配的问题,不但是在速率不匹配的时候能够有地方暂存任务,而且能在队列满或空的时候让线程进行阻塞,让出CPU的时间.这里对于阻塞两字加粗,是因为其实Java的线程在这个时候是等待(WAITING)状态而不是阻塞(BLOCKED),这个容易引起歧义. 下…
本节我们先会来复习一下java.util.concurrent下面的一些并发容器,然后再会来简单看一下各种同步器. ConcurrentHashMap和ConcurrentSkipListMap的性能 首先,我们来测试一下ConcurrentHashMap和ConcurrentSkipListMap的性能. 前者对应的非并发版本是HashMap,后者是跳表实现,Map按照Key顺序排序(当然也可以提供一个Comparator进行排序). 在这个例子里,我们不是简单的测试Map读写Key的性能,而…
本节我们来研究下并发包中的Atomic类型. AtomicXXX和XXXAdder以及XXXAccumulator性能测试 先来一把性能测试,对比一下AtomicLong(1.5出来的).LongAdder(1.8出来的)和LongAccumulator(1.8出来的)用于简单累加的性能. 程序逻辑比较简单,可以看到我们在最大并发10的情况下,去做10亿次操作测试: @Slf4j public class AccumulatorBenchmark { private StopWatch stop…
和我之前的Spring系列文章一样,我们会以做一些Demo做实验的方式来复习一些知识点. 本文我们先从Java并发中最最常用的线程池开始. 从一个线程池实验开始 首先我们写一个方法来每秒一次定时输出线程池的基本信息: private void printStats(ThreadPoolExecutor threadPool){ Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> { log.info("…
这个专题我发现怎么慢慢演化为性能测试了,遇到任何东西我就忍不住去测一把.本文我们会大概看一下各种锁数据结构的简单用法,顺便也会来比拼一下性能. 各种并发锁 首先,我们定一个抽象基类,用于各种锁测试的一些公共代码: 我们需要使用锁来保护counter和hashMap这2个资源 write字段表示这个线程是执行写操作还是读操作 每一个线程都会执行loopCount次读或写操作 start的CountDownLatch用于等待所有线程一起执行 finish的CountDownLatch用于让主线程等待…
Hashmap 和 Concurrenthashmap Hashmap 不适合并发,应该使用ConcurrentHashMap . 这是很多人都知道的,但是为什么呢? 可以先看一下这两篇文章. JDK7与JDK8中HashMap的实现 和 谈谈HashMap线程不安全的体现. 由这两篇文章我们可以知道 : Hashmap 不适合并发的原因是当Hashmap扩容的时候,迁移会产生回环. Hashmap 在JDK1.7 解决冲突的方法是生成链表,而1.8是生成红黑树. 明白了Hashmap之后,我们…
之前介绍了Java并发的基础知识和使用案例分析,接下来我们正式地进入Java并发的源码分析阶段,本文作为源码分析地开篇,源码参考JDK1.8 OverView: JDK1.8源码中的注释提到:ConcurrentHashMap是一种提供完整的并发检索和对于并发更新有高预测性的散列表,遵循了与HashMap相同的功能性规格,并包含与HashTable每个方法都对应的方法.虽然所有操作都是线程安全的,但检索操作并不牵涉任何锁,不支持任何锁住整个散列表来保护所有的访问. ConcurrentHashM…
一.从原子操作开始 从相对简单的Atomic入手(java.util.concurrent是基于Queue的并发包,而Queue,很多情况下使用到了Atomic操作,因此首先从这里开始). 很多情况下我们只是需要一个简单的.高效的.线程安全的递增递减方案.注意,这里有三个条件: 简单,意味着程序员尽可能少的操作底层或者实现起来要比较容易: 高效意味着耗用资源要少,程序处理速度要快: 线程安全也非常重要,这个在多线程下能保证数据的正确性. 这三个条件看起来比较简单,但是实现起来却难以令人满意. 通…
一.Unsafe Java无法直接访问底层操作系统,而是通过本地(native)方法来访问.不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作. 这个类尽管里面的方法都是public的,但是并没有办法使用它们,JDK API文档也没有提供任何关于这个类的方法的解释.总而言之,对于Unsafe类的使用都是受限制的,只有授信的代码才能获得该类的实例,当然JDK库里面的类是可以随意使用的. Unsafe类是在sun.misc包下,不属于Java标准.但是很多…
个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.线程安全性-原子性-atomic-1 1.线程安全性 定义: 当某个线程访问某个类时,不管运行时环境采用何种调度方式或者这些锦城南将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的. 特点: 原子性:提供了互斥访问,同一时刻只能有一个线程来对它进行操作 可见性:一个线程对主内存的修改可以及时的被其他线程观察到 有序性:一个线程观察其他…