JUC-java并发包
文章平均质量分 79
wyaoyao93
小白
展开
-
并行流Parallel Stream和Spliterator接口
文章目录1 Parallel 入门2 Spliterator 接口2.1 Spliterator接口方法详解2.2 自定义Spliterator及Stream1 Parallel 入门 public static void main(String[] args) { long sum = 0L; for (long l = 0; l < 10_000_000; l++) { sum += l; }; }最简单传统的写法就是上面这样我们原创 2021-04-27 12:59:14 · 291 阅读 · 0 评论 -
CompletableFuture
文章目录1 介绍2 CompletableFuture的快速入门2.1 当作Future使用2.2 任务的异步运行2.2.1 异步执行Supplier类型的任务2.2.2 异步执行Runnable类型的任务2.3 异步任务链2.3.1 thenApply: 以同步的方式继续处理上一个异步任务的结果2.3.2 thenApplyAsync:以异步的方式继续处理上一个异步任务的结果。2.3.3 thenAcceptAsync:以异步的方式消费上一个异步任务的结果。2.3.4 thenRun:以同步的方式执行Ru原创 2021-04-27 11:19:08 · 221 阅读 · 0 评论 -
CompletionService
文章目录1 ExecutorService执行批量任务的缺陷3 CompletionService详解3.1 快速入门3.2 方法和构造方式3.2.1 构造3.2.2 提交任务3.2.3 获取futrue1 ExecutorService执行批量任务的缺陷Future接口提供了一种在未来某个时间节点判断异步任务是否完成执行、获取运算结果等操作的方式。如果在异步任务仍在继续运行之时执行get方法,会使得当前线程进入阻塞直到异步任务运行结束(正常结束/异常结束)。因此无论是通过ExecutorServi原创 2021-04-27 09:17:37 · 166 阅读 · 0 评论 -
ForkJoinPool
文章目录1 Fork/Join Framework介绍2 ForkJoinPool中的任务2.1 RecursiveTask2.2 RecursiveAction1 Fork/Join Framework介绍Fork/Join框架是在JDK1.7版本中被Doug Lea引入的,Fork/Join计算模型旨在充分利用多核CPU的并行运算能力,将一个复杂的任务拆分(fork)成若干个并行计算,然后将结果合并(join)在JDK中,Fork/Join框架的实现为ForkJoinPool及ForkJoinTa原创 2021-04-27 08:12:04 · 209 阅读 · 1 评论 -
Google Guava的Future
文章目录1 大撒大撒1 大撒大撒原创 2021-04-26 18:16:54 · 572 阅读 · 0 评论 -
Future和Callback
文章目录1 Future和Callback1.1 快速认识1.2 取消任务1.3 异常捕获2 ExecutorService与Future2.1 提交Runnable类型任务2.2 invokeAny2.3 invokeAll3 Future的不足之处1 Future和Callback简单来说,Future代表着一个异步任务在未来的执行结果,这个结果可以在最终的某个时间节点通过Future的get方法来获得,关于Future更多的细节和原理,可参考多线程设计模式:Future设计模式对于长时间运行的任原创 2021-04-26 18:15:34 · 1730 阅读 · 0 评论 -
Executors详解
文章目录1 介绍2 方法2.1 FixedThreadPool2.2 SingleThreadPool2.3 CachedThreadPool2.4 ScheduledThreadPool2.5 WorkStealingPool1 介绍Executors,Java并发包中提供了类似于工厂方法的类,用于创建不同的ExecutorService,当然还包括拒绝策略、ThreadFactory等2 方法2.1 FixedThreadPool// 创建ExecutorService,指定核心线程数pu原创 2021-04-26 17:32:29 · 636 阅读 · 1 评论 -
Executor&ExecutorService
文章目录1 介绍2 ExecutorService实现一:ThreadPoolExecutor2.1 快速认识ThreadPoolExecutor2.2 ThreadPoolExecutor的构造2.3 执行任务2.4 ThreadFactory接口2.5 拒绝策略RejectedExecutionHandler2.6 ThreadPoolExecutor的其他方法3 ExecutorService实现二:ScheduledExecutorService3.1 ScheduledThreadPoolExec原创 2021-04-26 17:13:11 · 345 阅读 · 0 评论 -
并发容器:ConcurrentMap(并发映射)
文章目录1 介绍2 ConcurrentHashMap2.1 JDK1.8版本以前的ConcurrentHashMap内部结构2.2 JDK1.8版本ConcurrentHashMap的内部结构3 ConcurrentSkipListMap简介1 介绍Map是一个接口,它的实现方式有很多种,比如常见的HashMap、LinkedHashMap,但是这些Map的实现并不是线程安全的,在多线程高并发的环境中会出现线程安全的问题。Hashtable或者SynchronizedMap虽然是线程安全的,但是在多线原创 2021-04-26 13:04:03 · 492 阅读 · 0 评论 -
并发容器:ConcurrentQueue(并发队列)简单介绍
文章目录1 介绍1 介绍在Java中有没有一种队列的实现方式可以不用关心临界值的判断,操作该队列的线程也不会被挂起并且等待被其他线程唤醒,我们只是单纯地向该队列中插入或者获取数据,并且该队列是线程安全的,是可以应用于高并发多线程的场景中呢?在JDK1.5版本以前要实现这些要求我们大致有两种方式,具体如下:通过synchronized关键字对非线程安全的队列或者链表的操作方法进行同步。使用Collections类的同步方法但是synchronized关键字相对于显式锁Lock甚至无锁的实现方式来原创 2021-04-26 12:50:54 · 1478 阅读 · 0 评论 -
并发容器:阻塞队列之LinkedTransferQueue
文章目录1 介绍2 TransferQueue的方法2.1 transfer方法1 介绍TransferQueue是一个继承了BlockingQueue的接口,并且增加了若干新的方法。LinkedTransferQueue是TransferQueue接口的实现类,其定义为一个无界的队列,具有FIFO的特性。这里就只介绍继承自TransferQueue的方法public interface TransferQueue<E> extends BlockingQueue<E> {原创 2021-04-26 11:39:18 · 178 阅读 · 0 评论 -
并发容器:阻塞队列之SynchronousQueue
文章目录1 介绍2 代码示例:数据交换1 介绍SynchronousQueue也是实现自BlockingQueue的一个阻塞队列,每一次对其的写入操作必须等待(阻塞)其他线程进行对应的移除操作,SynchronousQueue的内部并不会涉及容量、获取size,就连peek方法的返回值永远都将会是null,除此之外还有更多的方法在SynchronousQueue中也都未提供对应的支持(列举如下),因此在使用的过程中需要引起注意,否则会使得程序的运行出现不符合预期的错误。clear():清空队列的方法原创 2021-04-26 08:50:48 · 147 阅读 · 0 评论 -
并发容器:阻塞队列之DelayQueue
文章目录1 介绍2 基本使用2.1 入门演示1 介绍DelayQueue也是一个实现了BlockingQueue接口的“无边界”阻塞队列,但是该队列却是非常有意思和特殊的一个队列(存入DelayQueue中的数据元素会被延迟单位时间后才能消费),在DelayQueue中,元素也会根据优先级进行排序,这种排序可以是基于数据元素过期时间而进行的(比如,你可以将最快过期的数据元素排到队列头部,最晚过期的数据元素排到队尾)。对于存入DelayQueue中的元素是有一定要求的:元素类型必须是Delayed接原创 2021-04-25 18:18:54 · 161 阅读 · 0 评论 -
并发容器:阻塞队列之LinkedBlockingQueue
文章目录1 介绍1 介绍ArrayBlockingQueue是基于数组实现的FIFO“有边界”队列,PriorityBlockingQueue也是基于数组实现的,但它是“无边界”的优先级队列,由于存在对数据元素的排序规则,因此PriorityBlockingQueue并不能提供FIFO的约束担保LinkedBlockingQueue是“可选边界”基于链表实现的FIFO队列。LinkedBlockingQueue队列的边界可选性是通过构造函数来决定的,当我们在创建LinkedBlockingQueue原创 2021-04-25 17:23:39 · 139 阅读 · 0 评论 -
并发容器:阻塞队列之PriorityBlockingQueue
文章目录1 介绍2 使用2.1 构造2.2 不存在阻塞写方法2.3 优先级队列读方法1 介绍PriorityBlockingQueue优先级阻塞队列是一个“无边界”阻塞队列,该队列会根据某种规则(Comparator)对插入队列尾部的元素进行排序,因此该队列将不会遵循FIFO(first-in-first-out)的约束2 使用2.1 构造只要应用程序的内存足够使用,理论上,PriorityBlockingQueue存放数据的数量是“无边界”的,**在PriorityBlockingQueue内部原创 2021-04-25 17:16:51 · 150 阅读 · 0 评论 -
并发容器:阻塞队列之ArrayBlockingQueue
文章目录1 介绍2 API介绍2.1 阻塞式写方法2.2 非阻塞式写方法2.3 阻塞式读方法2.4 非阻塞式读方法3 生产者消费者1 介绍ArrayBlockingQueue是一个基于数组结构实现的FIFO阻塞队列,在构造该阻塞队列时需要指定队列中最大元素的数量(容量)。当队列已满时,若再次进行数据写入操作,则线程将会进入阻塞,一直等待直到其他线程对元素进行消费。当队列为空时,对该队列的消费线程将会进入阻塞,直到有其他线程写入数据。该阻塞队列中提供了不同形式的读写方法。2 API介绍2.1 阻塞式写原创 2021-04-25 17:02:34 · 287 阅读 · 0 评论 -
并发工具:Guava之RateLimiter
文章目录1 介绍2 RateLimiter的基本使用1 介绍RateLimiter,顾名思义就是速率(Rate)限流器(Limiter),事实上它的作用正如名字描述的那样,经常用于进行流量、访问等的限制,这一点与3.4节中介绍过的Semaphore非常类似,但是它们的关注点却完全不同,RateLimiter关注的是在单位时间里对资源的操作速率(在RateLimiter内部也存在许可证(permits)的概念,因此可以理解为在单位时间内允许颁发的许可证数量),而Semaphore则关注的是在同一时间内最多原创 2021-04-25 14:27:06 · 229 阅读 · 0 评论 -
并发工具:Guava之Monitor
文章目录1 Monitor介绍2 入门案例3 Monitor的其他方法1 Monitor介绍无论使用对象监视器的wait notify/notifyAll还是Condition的await signal/ signalAll方法调用,我们首先都会对共享数据的临界值进行判断,当条件满足或者不满足的时候才会调用相关方法使得当前线程挂起,或者唤醒wait队列/set中的线程,因此对共享数据临界值的判断非常关键,Guava的Monitor工具提供了一种将临界值判断抽取成Guard的处理方式,可以很方便地定义若干原创 2021-04-25 14:19:02 · 237 阅读 · 0 评论 -
并发工具:StampedLock
文章目录1 读写锁的饥饿写问题2 StampedLock的使用2.1 替代ReentrantLock2.2 替代ReentrantReadWriteLock2.3 乐观读模式3 总结1 读写锁的饥饿写问题所谓的饥饿写是指在使用读写锁的时候,读线程的数量远远大于写线程的数量,导致锁长期被读线程霸占,写线程无法获得对数据进行写操作的权限从而进入饥饿的状态(当然可以在构造读写锁时指定其为公平锁,读写线程获得执行权限得到的机会相对公平,但是当读线程大于写线程时,性能效率会比较低下)。因此在使用读写锁进行数据一原创 2021-04-25 13:55:29 · 122 阅读 · 0 评论 -
并发工具:Condition
显式锁Lock可以用来替代synchronized关键字,那么Condition接口将会很好地替代传统的、通过对象监视器调用wait()、notify()、notifyAll()线程间的通信方式Condition对象是由某个显式锁Lock创建的,一个显式锁Lock可以创建多个Condition对象与之关联,Condition的作用在于控制锁并且判断某个条件(临界值)是否满足,如果不满足,那么使用该锁的线程将会被挂起等待另外的线程将其唤醒,与此同时被挂起的线程将会进入阻塞队列中并且释放对显式锁Lock的持.原创 2021-04-23 16:52:32 · 149 阅读 · 1 评论 -
并发工具:ReadWriteLock和ReentrantReadWriteLock
对共享资源的访问一般包括两种类型的动作,读和写(修改、删除等会引起资源发生变化的动作),当多个线程同时对某个共享资源进行读取操作时,并不会引起共享资源数据不一致情况的发生(如表3-2所示),因此这个时候如果仍旧让资源的访问互斥,就会显得有些不合情理了,Doug Lea在JDK 1.5版本引入了读写锁类,旨在允许某个特定时刻多线程并发读取共享资源,提高系统性能和访问吞吐量。可参考: 多线程设计模式: 读写锁分离设计模式文章目录1 读写锁的基本使用方法1 读写锁的基本使用方法使用的过程中需要分别派生.原创 2021-04-23 11:54:28 · 127 阅读 · 0 评论 -
并发工具:Lock和ReentrantLock
在Java1.5版本以前,我们开发多线程程序只能通过关键字synchronized进行共享资源的同步、临界值的控制,虽然随着版本的不断升级,JDK对synchronized关键字的性能优化工作一直都没有停止过,但是synchronized在使用的过程中还是存在着比较多的缺陷和不足,因此在1.5版本以后JDK增加了对显式锁的支持,显式锁Lock除了能够完成关键字synchronized的语义和功能之外,它还提供了很多灵活方便的方法,比如,我们可以通过显式锁对象提供的方法查看有哪些线程被阻塞,可以创建Cond.原创 2021-04-23 11:49:14 · 204 阅读 · 1 评论 -
并发工具:Phaser工具
文章目录1 Phaser工具介绍2 Phaser的基本用法(入门)2.1 将Phaser当作CountDownLatch来使用2.2 将Phaser当作CyclicBarrier来使用3 Phaser中的Phase(阶段)4 Phaser中的方法4.1 register方法1 Phaser工具介绍CountDownLatch、CyclicBarrier、Exchanger、Semaphore这几个同步工具都是JDK在1.5版本中引入的,Phaser是在JDK 1.7版本中才加入的;Phaser同样也是原创 2021-04-22 18:18:55 · 259 阅读 · 0 评论 -
并发工具:Semaphore工具(二)
文章目录1 Semaphore API介绍1.1 构造1.2 tryAcquire方法1.2.1 重载一1.2.2 重载二:超时设置1.2.3 重载三:获取多张许可1.3 acquire方法1.4 acquireUninterruptibly1.5 正确使用release1.5.1 release使用不当示例和改进1.5.2 扩展Semaphore增强release1.6 其他方法3 总结1 Semaphore API介绍1.1 构造/**定义Semaphore指定许可证数量,并且指定非公平的同步原创 2021-04-22 15:56:28 · 350 阅读 · 0 评论 -
并发工具:Semaphore工具(一)
文章目录1 Semaphore介绍2 入门案例:限制用户登录数量3 案例:使用Semaphore定义try lock1 Semaphore介绍Semaphore(信号量)是一个线程同步工具,主要用于在一个时刻允许多个线程对共享资源进行并行操作的场景。通常情况下,使用Semaphore的过程实际上是多个线程获取访问共享资源许可证的过程Semaphore(信号量)是一个线程同步工具,主要用于在一个时刻允许多个线程对共享资源进行并行操作的场景。通常情况下,使用Semaphore的过程实际上是多个线程获取访问共原创 2021-04-22 12:36:18 · 91 阅读 · 0 评论 -
并发工具:Exchanger工具
文章目录1 Exchanger工具介绍2 一对线程间的数据交换2.1 Demo1 Exchanger工具介绍Exchanger(交换器),从字面意思来看它的主要作用就是用于交换,Exchanger简化了两个线程之间的数据交互,并且提供了两个线程之间的数据交换点,Exchanger等待两个线程调用其exchange()方法。调用此方法时,交换机会交换两个线程提供给对方的数据。2 一对线程间的数据交换Exchanger在某种程度上可以看成是生产者和消费者模式的实现,但是它重点关注的是数据交换,所谓交换就原创 2021-04-22 09:47:08 · 185 阅读 · 0 评论 -
并发工具:CyclicBarrier(循环屏障)
文章目录1 CyclicBarrier介绍2 入门:等待所有子任务结束3 CyclicBarrier的循环特性和源码解读4 CyclicBarrier的其他方法5 CyclicBarrier VS CountDownLatch1 CyclicBarrier介绍CyclicBarrier(循环屏障),它也是一个同步助手工具,它允许多个线程在执行完相应的操作之后彼此等待共同到达一个障点(barrier point)CyclicBarrier也非常适合用于某个串行化任务被分拆成若干个并行执行的子任务,当所有原创 2021-04-20 14:45:33 · 369 阅读 · 0 评论 -
并发工具:CountDownLatch
文章目录1 CountDownLatch介绍2 入门程序:等待所有子任务结束3 CountDownLatch的总结1 CountDownLatch介绍当某项工作需要由若干项子任务并行地完成,并且只有在所有的子任务结束之后(正常结束或者异常结束),当前主任务才能进入下一阶段,CountDownLatch工具将是非常好用的工具,并且其所提供的操作方法还是线程安全的。参考文章:多线程设计模式:Latch(门阀)设计模式CountDownLatch(Count Down Latch,直译为倒计数门阀),原创 2021-04-20 11:25:34 · 110 阅读 · 0 评论 -
sun.misc.Unsafe介绍
juc包下的原子类型和并发容器都依赖了sun.misc.Unsafe这个类,该类是可以直接对内存进行相关操作的,甚至还可以通过汇编指令直接进行CPU的操作。文章目录1 sun.misc.Unsafe介绍2 如何获取Unsafe3 Unsafe应用3.1 绕过类构造函数完成对象创建3.2 直接修改内存数据3.3 类的加载1 sun.misc.Unsafe介绍sun.misc.Unsafe提供了非常多的底层操作方法,这些方法更加接近机器硬件(CPU/内存),因此效率会更高。不仅Java本身提供的很多AP原创 2021-04-20 10:40:55 · 347 阅读 · 0 评论 -
原子类型:AtomicFieldUpdater
要想使得共享数据的操作具备原子性,目前有两种方案:第一,使用关键字synchronized进行加锁;第二,将对应的共享数据定义成原子类型,比如将Int定义成AtomicInteger,其他数据类型则没有与之直接对应的原子类型,我们可以借助于AtomicReference进行封装。前者提供了互斥的机制来保证在同一时刻只能有一个线程对共享数据进行操作,所以说它是一种悲观的同步方式;后者采用CAS算法提供的Lock Free方式,允许多个线程同时进行共享数据的操作,相比较synchronized关键字,原子原创 2021-04-20 09:46:01 · 164 阅读 · 0 评论 -
原子类型:AtomicArray
int类型的数据可以封装成AtomicInteger类型,从此便可以通过原子性方法对int类型进行操作,如果高并发应用程序想要原子性地操作一个int类型数组中的int数据时,那么该如何操做呢?我们可以创建一个AtomicInteger类型的数组,其中的每一个元素都是AtomicInteger类型的,这样在高并发的应用程序中就可以原子性地操作数组中的某个元素了。事实上我们并不需要这样做,因为在Java原子包中提供了相应的原子性操作数组元素相关的类AtomicIntegerArray:提供了原子性操作i原创 2021-04-20 09:17:26 · 321 阅读 · 0 评论 -
原子类型:AtomicStampedReference
文章目录1 CAS算法ABA问题2 AtomicStampedReference详解2.1 AtomicStampedReference介绍2.2 构造方法2.3 方法3 总结1 CAS算法ABA问题AtomicInteger、AtomicBoolean、AtomicLong、AtomicReference这些原子类型,它们无一例外都采用了基于volatile关键字+CAS算法无锁的操作方式来确保共享数据在多线程操作下的线程安全性。volatile关键字保证了线程间的可见性,当某线程操作了被vola原创 2021-04-20 09:14:10 · 250 阅读 · 0 评论 -
原子类型:AtomicReference详解
文章目录1 AtomicReferencey引入2 AtomicReference的基本用法2.1 AtomicReference的构造2.2 方法1 AtomicReferencey引入AtomicReference类提供了对象引用的非阻塞原子性读写操作,并且提供了其他一些高级的用法对象的引用其实是一个4字节的数字,代表着在JVM堆内存中的引用地址,对一个4字节数字的读取操作和写入操作本身就是原子性的**,通常情况下,我们对对象引用的操作一般都是获取该引用或者重新赋值(写入操作),我们也没有办法对对原创 2021-04-19 18:06:56 · 43020 阅读 · 22 评论 -
原子类型:AtomicLong详解
与AtomicInteger非常类似,AtomicLong提供了原子性操作long类型数据的解决方案,AtomicLong同样也继承自Number类,AtomicLong所提供的原子性方法在使用习惯上也与AtomicInteger非常一致。这里就不多介绍1 compareAndSwapLong和compareAndSwapIntAtomicInteger类中最为关键的方法为compareAndSwapInt,同样,在AtomicLong类中也提供了类似的方法compareAndSwapLong,但是该原创 2021-04-19 16:32:55 · 2697 阅读 · 0 评论 -
原子类型:AtomicBoolean应用:显式锁
1 显式锁实现synchronized关键字存在的缺陷,其中,当某个线程在争抢对象监视器(object monitor)的时候将会进入阻塞状态,并且是无法被中断的,也就是说synchronized关键字并未提供一种获取monitor锁失败的通知机制,执行线程只能等待其他线程释放该monitor的锁进而得到一次机会,本节将借助于AtomicBoolean实现一个可立即返回并且退出阻塞的显式锁Lock关于synchronized关键字存在的缺陷可参考:自定义显式锁BooleanLockpublic c原创 2021-04-19 16:28:37 · 324 阅读 · 0 评论 -
原子类型:AtomicBoolean详解
文章目录1 AtomicBoolean的基本用法1.1 AtomicBoolean的创建1.2 AtomicBoolean值的更新1.3 其他方法2 AtomicBoolean内幕AtomicBoolean提供了一种原子性地读写布尔类型变量的解决方案,通常情况下,该类将被用于原子性地更新状态标识位1 AtomicBoolean的基本用法AtomicBoolean提供的方法比较少也比较简单,只对其做简单介绍,其基本原理与AtomicInteger极为类似。1.1 AtomicBoolean的创建//原创 2021-04-19 14:44:37 · 3770 阅读 · 0 评论 -
原子类型:AtomicInteger内幕(了解)
public class AtomicInteger extends Number implements java.io.Serializable { private static final long serialVersionUID = 6214790243416807050L; // Unsafe是由C++实现的,其内部存在着大量的汇编 CPU指令等代码,JDK实现的 private static final Unsafe unsafe = Unsafe.getUnsafe(原创 2021-04-19 14:12:37 · 83 阅读 · 0 评论 -
原子类型:AtomicInteger认识
1 原子类型介绍无论是基本数据类型还是引用类型的变量,只要被volatile关键字修饰,从JMM(Java Memory Model)的角度分析,该变量就具备了有序性和可见性这两个语义特质,但是它还是无法保证原子性。那么,什么是原子性呢?原子性是指某个操作或者一系列操作要么都成功,要么都失败,不允许出现因中断而导致的部分成功或部分失败的情况。比如,对int类型的加法操作就是原子性的,如x+1。但是我们在使用的过程中往往会将x+1的结果赋予另一个变量甚至是x变量本身,即进行x=x+1或者x++这样的操作,原创 2021-04-19 13:22:27 · 732 阅读 · 0 评论