多线程
文章平均质量分 90
业精勤而荒嬉
知其然知其所以然
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
JUC源码解析-ConcurrentHashMap1.8
前言1.8后的ConcurrentHashMap与之前有截然不同的设计,之前是分段锁的思想,通过采用分段锁Segment减少热点域来提高并发效率。1.8利用CAS+Synchronized来保证并发更新的安全,底层采用数组+链表+红黑树的存储结构。在此再一次膜拜Doug Lea大神,高山仰止。1.8的ConcurrentHashMap有6313行代码,之前大概是1000多行。这篇文章也...原创 2018-06-14 20:23:00 · 7007 阅读 · 0 评论 -
JUC源码解析-CopyOnWriteArrayList
利用写时复制来实现的一个线程安全的ArrayList类,任何对内部数组的更改操作都被锁保护,更改操作都是在拷贝的新数组上进行。public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private sta...原创 2019-01-29 01:49:34 · 1343 阅读 · 0 评论 -
volatile
作者:jiankunking 出处:https://blog.youkuaiyun.com/xunzaosiyecao/article/details/80410277提到volatile首先想到就是:保证此变量对所有线程的可见性,这里的 “可见性” 是指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。禁止指令重排序优化。 &nbs...转载 2019-01-29 03:34:13 · 198 阅读 · 0 评论 -
Java内存模型与volatile关键字
转载自:https://blog.youkuaiyun.com/jiankunking/article/details/5300100912.2硬件的效率与一致性由于计算机的存储设备与处理器的运算速度有几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cache)来作为内存与处理器之间的缓冲:将运算需要使用到的数据复制到缓存中,让运算能快速进行,当运算结束后...转载 2019-01-29 18:15:08 · 285 阅读 · 0 评论 -
JUC源码解析-阻塞队列-PriorityBlockingQueue
PriorityBlockingQueue需要对堆排序有了解,推荐 排序六 堆排序PriorityBlockingQueue 底层是个最小堆。 private static final int DEFAULT_INITIAL_CAPACITY = 11; private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE -...原创 2019-03-01 16:53:03 · 264 阅读 · 0 评论 -
JUC源码解析-阻塞队列-DelayQueue
DelayQueue是一个支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延迟期满时才能从队列中提取元素。我们可以将DelayQueue运用在以下应用场景:缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从De...原创 2019-03-03 02:39:23 · 302 阅读 · 0 评论 -
JUC源码解析-阻塞队列-SynchronousQueue
SynchronousQueue 是一个同步阻塞队列,它的每个插入操作都要等待其他线程相应的移除操作,反之亦然。SynchronousQueue 像是生产者和消费者的会合通道,它比较适合“切换”或“传递”这种场景:一个线程必须同步等待另外一个线程把相关数据传递给它。不同于之前的 ArrayBlockingQueue,LinkedBlockingQueue…对于它们来说生产者线程将数据放入存储空间...原创 2019-03-12 01:47:17 · 374 阅读 · 0 评论 -
JMM与happens-before
首先关于Java并发的通信机制是基于共享内存实现的,线程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通信,这对程序员是透明的,我们需要理解其工作机制,以防止内存可见性问题,从而编写出正确同步的代码。同步指用于控制不同线程间操作发生相对顺序的机制,我们需要显式的指定方法或代码块需要在线程之间互斥执行。由于Java的这种通信方式,一个线程要跟另一个通信,何时将共享变量刷新到内存,另一...原创 2019-03-23 15:37:59 · 1530 阅读 · 1 评论 -
Java并发之Future模式
本篇是《图解Java多线程设计模式》第九章的读书笔记。Future的意思是未来,假设有一个方法需要花费很长的时间才能获取到运行结果,那么与其一直等待不如先去忙别的,等你完成我再来拿。来看看示例代码:先来看下各个类之间的关系:Data接口RealData 与 FutureData 实现的接口public interface Data { String getContent()...原创 2019-04-07 21:25:02 · 513 阅读 · 0 评论 -
ThreadLocal的介绍与使用
本篇是《图解Java多线程设计模式》第十一章的读书笔记。有一个储物室,里面有很多储物柜。每个人拿着自己的钥匙去开自己的储物柜,虽然进同一个储物室,但彼此互不干扰。这就是 Thread-Local Storage 线程中的局部存储空间。来看一个例子:每个线程将信息打印到自己的日志文件中。TSLog :打印类,每个线程都有自己的 TSLog 对象,向自己的日志文件中打印信息。public cl...原创 2019-04-08 09:49:52 · 489 阅读 · 0 评论 -
JUC源码解析-CyclicBarrier
当你有这种需求:想要每执行N个线程后就执行某个任务,那么你就可以用CyclicBarrier。举个例子:四个线程,每个线程在执行完自己的任务后停下来等待其它三个线程执行完任务,全部执行完后,四个线程继续往下执行。public class CyclicBarrierTest { static class Writer extends Thread { priv...原创 2018-05-19 20:51:00 · 362 阅读 · 0 评论 -
AQS-独占与共享
共享操作多在CountDownLatch与Semaphore两篇中详细介绍过,要了解详情请去这两篇看。AQS的功能可以分为两类:独占与共享;如ReentrantLock利用了其独占功能,CountDownLatch,Semaphore利用了其共享功能。AQS的静态内部类Node里有两个变量,独占锁与共享锁在创建自己的节点时(addWaiter方法)用于表明身份,它们会被赋值给Node的nex...原创 2018-05-18 00:48:00 · 1602 阅读 · 0 评论 -
多线程设计模式:Thread-Per-Message模式
为每个命令或请求新分配一个线程,由这个线程来执行处理,这就是Thread-Per-Message模式。举个例子: 名字 说明 Main 向Host发送字符,显示请求的类 Host 针对请求创建线程的类 Helper 提供字符显示功能的被动类...原创 2018-09-19 16:29:04 · 448 阅读 · 0 评论 -
JUC源码解析-线程池-ThreadPoolExecutor
ThreadPoolExecutor首先来看看线程池的主要工作流程图接下来看看源码实现: private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); private static final int COUNT_BITS = Integer.SIZE - 3; p...原创 2018-05-08 12:46:00 · 436 阅读 · 1 评论 -
JUC源码解析-线程池-FutureTask
前一篇文章主要从execute方法来分析ThreadPoolExecutor,还有一种提交任务的方式,就是ExecutorService的submit,该方法返回FutureTask,这篇文章就来分析二者的结合。继承图submit方法的主要实现在 AbstractExecuotrService: public <T> Future<T> ...原创 2018-05-10 15:11:00 · 1201 阅读 · 0 评论 -
JUC源码解析-ReentrantLock
AQS是同步器的基础,要先了解AQS的实现使用实例:Lock lock = new ReentrantLock();Condition condition = lock.newCondition();lock.lock();try { while(条件判断表达式) { condition.wait(); } // 处理逻辑} finally { l...原创 2018-05-14 14:53:00 · 454 阅读 · 0 评论 -
实现一个读写锁
翻译自Read / Write Locks in Java对于读取操作数量明显大于写入操作的场景,使用读写锁。先来自己实现个读写锁,之后再分析JUC包下的ReentrantReadWriteLock。读写锁的规则:当有写操作正在运行,则读操作应该等待;当有读操作正在运行,写操作也要等待。读操作与读操作之间不会阻塞,也就是读读可以,写读,写写都不行。这里还有个问题那就是饥饿,于是我们有加...翻译 2018-05-25 18:56:00 · 1942 阅读 · 3 评论 -
JUC源码解析-ReentrantReadWriteLock
ReentrantLock是独占锁,只允许一个线程执行;CountDownLatch,Semaphore等是共享锁;它们分别利用了AQS的独占与共享功能;那么如果在读操作远多于写操作的情况下该如何选择?读写锁,之前的文章中介绍了如何自己实现一个读写锁,还实现了重入功能,读读,写写,读写,写读四种重入。现在来看看JUC包下的ReentrantReadWriteLock的实现。先来大致了解下Reen...原创 2018-05-30 16:01:00 · 361 阅读 · 0 评论 -
JUC源码解析-Condition
生产者消费者实例:public class ProductorCustom<T> { private final ReentrantLock lock = new ReentrantLock(); private Condition putButFull = lock.newCondition(); private Condition tackButEm...原创 2018-05-14 17:59:00 · 465 阅读 · 0 评论 -
JUC与生产者消费者
前面一篇文章介绍了生产者消费者模式,这篇来看看JUC包下的哪些类与该模式有关。生产者消费者模式中有个中间类Channel,对于数据Data起到通道作用,还确保了Producer与Consumer这些线程的协调运行。在前篇文章所举的例子中的Table类担任这个角色,内部是使用数组实现的队列配合synchronized关键字。而在JUC包下提供了BlockingQueue接口及其实现类,它们相当于C...原创 2019-01-20 13:19:53 · 521 阅读 · 0 评论 -
JUC源码解析-CountDownLatch
CountDownLatch允许一个或多个线程等待其它线程完成操作。CountDownLatch的构造函数接收一个int类型的参数作为计数器,想等待N个任务线程完成就传N。当countDown方法被调用N就会减一,await方法会阻塞当前线程直到N变为0。主要的功能就是通过await()方法来阻塞线程,然后等待计数器减少到0了,再唤起那些等待的线程继续;即你想要某些线程等待另一些线程执行完...原创 2018-05-16 23:57:00 · 423 阅读 · 0 评论 -
JUC源码解析-Semaphore
Semaphore信号量是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。开始前建议先看之前AQS的文章,以及很多共享锁的代码在之前CountDownLatch文章里介绍过了。看看例子:public class SemaphoreTrain { static class Worker extends Thread { pri...原创 2018-05-17 17:11:00 · 1568 阅读 · 0 评论 -
ThreadLocal源码解析
什么是ThreadLocal?它是属于线程自己的小仓库。关于它的使用与介绍看这一篇:ThreadLocal的介绍与使用关于ThreadLocal的原理,理清四个角色关系:Thread,ThreadLocal,ThreadLocalMap,Entry:在Thread中有个变量指向ThreadLocalMap ThreadLocal.ThreadLocalMap thread...原创 2019-04-09 11:05:42 · 532 阅读 · 0 评论
分享