摘要:
PriorityBlockingQueue 优先级队列,线程安全(添加、读取都进行了加锁)、无界、读阻塞的队列,底层采用的堆结构实现(二叉树),默认是小根堆,最小的或者最大的元素会一直置顶,每次获取都取最顶端的数据。 队列创建 小根堆 PriorityBlockingQueue<Integer> c 阅读全文
摘要:
DelayQueue是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,在创建元素时,可以指定多久才能从队列中获取当前元素。只有延时期满后才能从队列中获取元素。这种队列是有序的,即队头对象的延迟到期时间最长。注意:不能将null元素放置到这种队列中。 队列创建 Block 阅读全文
摘要:
在并发编程中存在线程安全问题,主要原因有: 存在共享数据 多线程共同操作共享数据。 关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时synchronized可以保证一个线程的变化可见(可见性),即可以代替volatile。 设计同步器的意义 多线程编程 阅读全文
摘要:
LinkedBlockingQueue 是一个基于链表的无界队列(理论上有界),队列按照先进先出的顺序进行排序。LinkedBlockingQueue不同于ArrayBlockingQueue,它如果不指定容量,默认为 Integer.MAX_VALUE,也就是无界队列。所以为了避免队列过大造成机器 阅读全文
摘要:
ArrayBlockingQueue 由数组支持的有界阻塞队列,队列基于数组实现,容量大小在创建 ArrayBlockingQueue 对象时已经定义好。 此队列按照先进先出(FIFO)的原则对元素进行排序。支持公平锁和非公平锁,默认采用非公平锁。其数据结构如下图: 注:每一个线程在获取锁的时候可能 阅读全文
摘要:
在Java 集合框架中,我们介绍了List集合中最常用的子类ArrayList和LinkedList,但是它们都不保证多线程安全。如果多个线程同时读取和修改数据,就会产生冲突。 要实现多线程安全,可以使用同步集合Vector以及使用Collections类中synchronizedXXX系列方法。它 阅读全文
摘要:
假如我们现在有这样的需求,有一个仓库,我们可以存东西和取东西,仓库有存储上限。当仓库已满的时候,存东西的人就必须等待,直到有人取走东西。当仓库为空的时候,取东西的人必须等待,直到有人存入东西。 这是一个典型的生产者消费者问题。这里有两个条件,仓库已满的条件和仓库为空的条件,用条件让线程等待,这个让我 阅读全文
摘要:
Phaser简介 Phaser是JDK1.7开始引入的一个同步工具类,适用于一些需要分阶段的任务的处理。它的功能与 CyclicBarrier和CountDownLatch有些类似,类似于一个多阶段的栅栏,并且功能更强大,我们来比较下这三者的功能: 同步器 作用 CountDownLatch 倒数计 阅读全文
摘要:
Exchanger用于两个线程之间进行数据交换,每个线程调用exchage方法到达各自的同步点,当且仅当两个线程都达到同步点的时候,才可以交换信息,否则先到达同步点的线程必须等待。 Exchanger简介 Exchanger——交换器,是JDK1.5时引入的一个同步器,从字面上就可以看出,这个类的主 阅读全文
摘要:
Semaphore([' seməf :(r)])的主要作用是控制线程并发的数量。我们可以将Semaphore想象成景区的一个门卫,这个门卫负责发放景区入园的许可证。 景区为了游客的入园观赏体验,决定最多允许200个有个同时在园内观赏。那么这个门卫在每天开园的时候手中都会有200张许可证,每当一个游 阅读全文
摘要:
CyclicBarrier的简单概述 现实生活中我们经常会遇到这样的情景,在进行某个活动前需要等待人全部都齐了才开始。例如吃饭时要等全家人都上座了才动筷子,旅游时要等全部人都到齐了才出发,比赛时要等运动员都上场后才开始。 在JUC包中为我们提供了一个同步工具类能够很好的模拟这类场景,它就是Cycli 阅读全文
摘要:
CountDownLatch一般被称作"计数器",作用大致就是数量达到了某个点之后计数结束,才能继续往下走。 CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程执行完后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有框架服务之后执行。 原理 阅读全文
摘要:
Condition简介 在java中,对于任意一个java对象,它都拥有一组定义在java.lang.Object上监视器方法,包括wait(),wait(long timeout),notify(),notifyAll(),这些方法配合synchronized关键字一起使用可以实现等待/通知模式。 阅读全文
摘要:
LockSupport是一个编程工具类,主要是为了阻塞和唤醒线程用的。使用它我们可以实现很多功能。 LockSupport简介 LockSupport是什么 LockSupport是一个线程工具类,所有的方法都是静态方法,可以让线程在任意位置阻塞,也可以在任意位置唤醒。 它的内部其实两类主要的方法: 阅读全文
摘要:
ReentrantReadWriteLock是做什么作用的呢? 我们知道,多线程操作同一数据时,如果不加锁,会产生冲突。其实对数据的操作就是两种,读和写。那么什么情况下会发生冲突呢? 两个线程同时写,会产生冲突。 一个线程写,一个线程读,也会产生冲突,因为读取的可能不是最新写的内容。 两个线程同时读 阅读全文
摘要:
JUC框架中最常用的锁ReentrantLock(可重入独占锁,也叫可重入互斥锁)。 public class ReentrantLock implements Lock, java.io.Serializable {} ReentrantLock实现Lock接口,以及Serializable可序列 阅读全文
摘要:
AQS是JUC锁框架中最重要的类,通过它来实现独占锁和共享锁的。本章是对AbstractQueuedSynchronizer源码的完全解析,分为四个部分介绍: CLH队列即同步队列:储存着所有等待锁的线程 独占锁 共享锁 Condition条件 注:还有一个AbstractQueuedLongSyn 阅读全文
摘要:
Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自JDK 8)、使用场景进行举例,为读者介绍主流锁的知识点,以及不同的锁的适用场景。 Java中往往是按照是否含有某一特性来定义锁,我们通过特性将锁进行分组归类,再使用对比的方 阅读全文
摘要:
在JDK1.5已经提供了Future和Callable的实现,可以用于阻塞式获取结果,如果想要异步获取结果,通常都会以轮询的方式去获取结果,如下: //定义一个异步任务 Future<String> future = executor.submit(()->{ Thread.sleep(2000); 阅读全文
摘要:
当我们创建一个线程时,我们想获取线程运行完成后的结果,一般使用回调的方式。例如: interface Callable { void call(int num); } public class FutureTest { public static void main(String[] args) { 阅读全文