![](https://img-blog.csdnimg.cn/direct/b0386edb5dfc4902a3f9bf09d4dd06c1.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
并发编程
文章平均质量分 88
并发编程:同时处理多个任务
Jerryean99
奋斗不息,编码不止,大家好,我是来自重庆的Jerryean99,一个坚信技术可以创造未来的Java程序猿!
展开
-
【第二十三篇】四种线程池的分类和简单应用 【重点】
1.1 缓存线程池(newCachedThreadPool)1.1.1 作用创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们,并在需要时使用提供的 ThreadFactory 创建新线程。1.1.2 特征(1)线程池中数量没有固定,可达到最大值(Interger. MAX_VALUE)(2)线程池中的线程可进行缓存重复利用和回收(回收默认时间为1分钟)(3)当线程池中,没有可用线程,会重新创建一个线程1.1.3 创建方式Executors.newCache原创 2022-03-02 16:46:02 · 815 阅读 · 3 评论 -
【第二十二篇】Java NIO详解【重点】
1.1 JAVA NIO简介由于之前老的I/O类库是阻塞I/O,New I/O类库的目标就是要让Java支持非阻塞I/O,所以,更多的人喜欢称之为非阻塞I/O(Non-block I/O)java 1.4版本推出了一种新型的IO API,与原来的IO具有相同的作用和目的;可代替标准java IO,只是实现的方式不一样,NIO是面向缓冲区、基于通道的IO操作;通过NIO可以提高对文件的读写操作。基于这种优势,现在使用NIO的场景越来愈多,很多主流行的框架都使用到了NIO技术,如Tomcat、Netty、原创 2022-03-02 16:17:31 · 765 阅读 · 1 评论 -
【第二十一篇】LockSupport(park/unpark)和Object类的wait/notify的区别
1.1 wait、notify方法介绍wait、notify、notifyAll是Object对象中提供的用于线程挂起和唤醒的方法。wait、notify、notifyAll必须与synchronized关键字搭配使用。当调用obj.wait()的时候,会将当前线程挂起,并将其加入到obj对应的等待队列中。而调用obj.notify()的时候,会唤醒obj对应的等待队列中的其中一个线程!调用obj.notifyAll()的时候,会唤醒obj对应的等待队列中的全部线程。wait、notif原创 2022-03-02 15:14:10 · 668 阅读 · 2 评论 -
【第二十篇】阻塞队列之ArrayBlockingQueue原理简析【重点】
1.1 ArrayBlockingQueue介绍BlockingQueue是一个阻塞队列,在高并发场景是用得非常多的,比如在线程池中:如果运行线程数目大于核心线程数目时,也会尝试把新加入的线程放到一个BlockingQueue中去。队列的特性就是先进先出很容易理解,在java里头它的实现类主要有下图的几种,其中最常用到的是ArrayBlockingQueue、LinkedBlockingQueue及SynchronousQueue这三种,本文我们主要来讲解ArrayBlockingQueue。原创 2022-03-02 14:34:55 · 6250 阅读 · 2 评论 -
【第十九篇】阻塞队列之LinkedBlockingQueue原理简析【重点】
1.1 概要本文主要是对Java并发中阻塞队列的LinkedBlockingQueue进行深入分析。 阻塞队列与我们平常接触的普通队列(LinkedList或ArrayList等)的最大不同点,在于阻塞队列的阻塞添加和阻塞删除方法。阻塞添加所谓的阻塞添加是指当阻塞队列元素已满时,队列会阻塞加入元素的线程,直队列元素不满时才重新唤醒线程执行元素加入操作。阻塞删除阻塞删除是指在队列元素为空时,删除队列元素的线程将被阻塞,直到队列不为空再执行删除操作(一般都会返回被删除的元素)1.2 原理原创 2022-03-02 11:41:52 · 5012 阅读 · 7 评论 -
【第十八篇】JDK1.7中HashMap并发成环的原因【重点】
1.1 概述 前面我们已经探究过HashMap的源码,本文主要来说明HashMap JDK1.7版本并发成环的原因。1.2 原因探究1.2.1 成环原因多线程扩容1.2.2 源码探究hashmap成环原因的代码出现在transfer代码中,看以下代码,transfer(),在实际扩容时候把原来数组中的元素放入新的数组中。void resize(int newCapacity) { Entry[] oldTable = table; int oldCapacity = o原创 2022-03-02 09:58:27 · 1184 阅读 · 5 评论 -
【第十七篇】ConcurrentHashMap源码解析与应用详解【重点】
1.1 概述 HashTable是一个线程安全的类,它使用synchronized来锁住整张Hash表来实现线程安全,即每次锁住整张表让线程独占。 在并发使用到HashMap的时候,往往不建议直接用HashMap,因为HashMap在并发写数据的时候容易因为rehash的过程产生环形链表的情况。所以在并发使用Map结构时,一般建议使用ConcurrentHashMap。1.2 JDK1.7与1.8的ConcurrentHashMap1.2.1 JDK1.7 的ConcurrentHashMap原创 2022-03-01 17:03:13 · 1067 阅读 · 3 评论 -
【第十六篇】CopyOnWriteArrayList源码解析与应用详解【重点】
ArrayList是大家用的再熟悉不过的集合了,而此集合设计之初也是为了高效率,并未考虑多线程场景下,所以也就有了多线程下的CopyOnWriteArrayList这一集合。原创 2022-03-01 16:17:21 · 658 阅读 · 1 评论 -
【第十五篇】ForkJoinPool的使用及基本原理【重点】
1.1 概述Fork/Join框架是Java7提供了的一个用于并行执行任务的框架。ForkJoinPool是Java中提供了一个线程池,特点是用来执行分治任务。主题思想是将大任务分解为小任务,然后继续将小任务分解,直至能够直接解决为止,然后再依次将任务的结果合并。1.2 原理详解 ForkJoinPool是自java7开始,jvm提供的一个用于并行执行的任务框架。其主旨是将大任务分成若干小任务,之后再并行对这些小任务进行计算,最终汇总这些任务的结果。得到最终的结果。其广泛用在java8的stream原创 2022-03-01 15:43:44 · 16740 阅读 · 11 评论 -
【第十四篇】CompletionService类源码解析与应用详解【重点】
1.1 概述当我们使用ExecutorService启动多个Callable时,每个Callable返回一个Future,而当我们执行Future的get方法获取结果时,可能拿到的Future并不是第一个执行完成的Callable的Future,就会进行阻塞,从而不能获取到第一个完成的Callable结果,那么这样就造成了很严重的性能损耗问题。我们一起来看一个例子:Future f1 = excutor.submit(c1);f1.get();Future f2 = excutor.submit(原创 2022-03-01 14:48:39 · 865 阅读 · 5 评论 -
【第十三篇】CompletableFuture类源码解析与应用详解【重点】
1.1 概述从上篇文章我们知道,使用Future获得异步执行结果时,要么调用阻塞方法get(),要么轮询看isDone()是否为true,这两种方法都不是很好,因为主线程也会被迫等待。 从Java 8开始引入了CompletableFuture,它针对Future做了改进,可以传入回调对象,当异步任务完成或者发生异常时,自动调用回调对象的回调方法。当任务执行完之后,会通知调用线程来执行回调方法。而在调用回调方法之前,调用线程可以执行其他任务,是非阻塞的。CompletableFuture还提供了串行原创 2022-03-01 11:34:00 · 1428 阅读 · 2 评论 -
【第十二篇】Java 线程池Future和FutureTask【重点】
1.1 概述 本文主要讲解Java线程池与Future和FutureTask的结合使用,通过本文的学习你可以轻松的在日常开发中运用线程池与Future和FutureTask的使用。Future的出现原因我们在Java线程池ThreadPoolExecutor详解中利用execute(Runnable r)方法来异步执行任务,但是有一个缺点,就是无法执行带有返回值的任务。1.2 原理详解1.2.1 结构图FutureTask实现了RunnableFuture接口,而RunnableFutu原创 2022-03-01 10:46:29 · 11094 阅读 · 2 评论 -
【第十一篇】Java线程池ThreadPoolExecutor使用详解【重点】
1.1 概述引入线程池的原因1、减少开销提升效率 减少线程的创建和销毁所花的时间以及系统资源的开销; 同时,提高系统响应速度,当有新任务到达时,通过复用已存在的线程,无需等待新线程的创建便可立即执行。2、提高线程的可管理性 方便管控线程并发数量。线程无限制的创建,可能会导致内存占用过多,从而产生OOM,并且会造成CPU过度切换,CPU切换线程是有时间成本的:需要保持当前执行线程的现场,并恢复要执行线程的现场。 对线程进行统一的分配、调优和监控,从而也提高响应速度;提供更强大的功能,延原创 2022-02-28 17:08:34 · 3312 阅读 · 13 评论 -
【第十篇】Java原子操作类详解【重点】
1.1 概述 在并发编程中很容易出现并发安全的问题,有一个很简单的例子就是多线程更新变量i=1,比如多个线程执行i++操作,就有可能获取不到正确的值,而这个问题,最常用的方法是通过Synchronized进行控制来达到线程安全的目的。但是由于Synchronized是采用的是悲观锁策略,并不是特别高效的一种解决方案。实际上,在J.U.C下的atomic包提供了一系列的操作简单,性能高效,并能保证线程安全的类去更新基本类型变量,数组元素,引用类型以及更新对象中的字段类型。atomic包下的这些类都是采用原创 2022-02-28 16:12:10 · 1553 阅读 · 12 评论 -
【第九篇】ReentrantReadWriteLock源码解析与应用详解【重点】
1.1 概述 ReentrantReadWriteLock是Lock的另一种实现方式,我们知道ReentrantLock是一个可重入独占锁,即同一时间只能有一个线程持有锁。对于写少读多的场景,读写锁相对于独占锁ReentrantLock有着很大的提升。因为独占锁每次读都要加锁解锁,耗费资源。 ReentrantReadWriteLock允许多个读线程同时访问,相对于排他锁,提高了并发性。在实际应用中,大部分情况下对共享数据(如缓存)的访问都是读操作远多于写操作,这时ReentrantRead原创 2022-02-28 15:36:33 · 565 阅读 · 3 评论 -
【第八篇】Semaphore源码解析与应用详解【重点】
1.1 概述 Semaphore是一个线程同步的辅助类,通常我们叫它信号量, 可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源,Semaphore常常被用作限流器,通过共享锁对资源进行限制。可以把它简单的理解成我们停车场入口立着的那个显示屏,每有一辆车进入停车场显示屏就会显示剩余车位减1,每有一辆车从停车场出去,显示屏上显示的剩余车辆就会加1,当显示屏上的剩余车位为0时,停车场入口的栏杆就不会再打开,车辆就无法进入停车场了,直到有一辆车从停车场出去为止。1.2 使用原创 2022-02-28 11:40:53 · 849 阅读 · 1 评论 -
【第七篇】CyclicBarrier源码解析与应用详解【重点】
1.1 概述 CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。 CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。1.2 源码解析首先,Cycl原创 2022-02-28 10:56:28 · 1153 阅读 · 2 评论 -
【第六篇】CountDownLatch源码解析与应用详解【重点】
1.1 背景 CountDownLatch是一种java.util.concurrent包下一个同步工具类,跟它一起被引入的工具类还有CyclicBarrier、Semaphore、concurrentHashMap和BlockingQueue。1.2 概念countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。实现原理:是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等原创 2022-02-28 10:01:31 · 596 阅读 · 8 评论 -
【第五篇】ReentrantLock原理详解【重点】
1.1 概述ReentrantLock是Java中的最常见的锁,本文主要讲解ReentrantLock的实现原理。 ReentrantLock主要利用CAS+AQS队列来实现,它是一种独占锁、可重入锁,它支持公平锁和非公平锁模式。1.2 ReentrantLock原理探究ReentrantLock原理之前我们先来看一个ReentrantLock的使用示例 private Lock lock = new ReentrantLock(); public void test(){ l原创 2022-02-25 17:20:45 · 2596 阅读 · 18 评论 -
【第四篇】一文让你轻松掌握AQS原理【重点】
【重要】Java中Synchronized原理详解以及锁的升级1.1 概述1.2 锁的分类1.1 概述 本次博客我们一起来讲解Synchronized的实现以及原理。1.2 锁的分类学习Java的过程中,会听到各种锁,比如显示锁、隐式锁、公平锁、非公平锁等等,下面提供一张图供大家参考:...原创 2022-02-25 15:11:26 · 2999 阅读 · 4 评论 -
【第三篇】Java中Synchronized原理详解以及锁的升级
【重要】Java中Synchronized原理详解以及锁的升级1.1 概述1.2 锁的分类1.3 引入synchronized1.4 Synchronized的使用1.4.1 修饰静态方法1.4.2 修饰非静态方法1.4.3 修饰代码块1.4.4 思考1.4.5 实现原理1.5 synchronized 锁的升级1.5.1 升级原理探索总结1.1 概述 本次博客我们一起来讲解Synchronized的实现以及原理。1.2 锁的分类学习Java的过程中,会听到各种锁,比如显示锁、隐式锁、公平锁、非公原创 2022-02-24 16:39:41 · 1292 阅读 · 2 评论 -
【第二篇】【并发重要原则】happens-before理解和应用
【重要】happens-before理解和应用1.1 happens-before的理解1.2 happens-before原则总结1.1 happens-before的理解结论:happens-before觉得着什么时候变量操作对你可见。 我们知道cpu的运行极快,而读取主存对于cpu而言有点慢了,在读取主存的过程中cpu一直闲着(也没数据可以运行),这对资源来说造成极大的浪费。所以慢慢的cpu演变成了多级cache结构,cpu在读cache的速度比读内存快了n倍。当线程在执行时,会保存临界资源原创 2022-02-24 14:53:42 · 702 阅读 · 1 评论 -
【第一篇】Java并发编程的三大特性:原子性、可见性、有序性
【重点】Java并发编程的三大特性原子性可见性有序性总结 Java并发编程中,往往涉及到三个性质:原子性、可见性。有序性。原子性熟悉数据库特性的我们都知道数据库也有原子性,数据库中的原子性是这样定义的:事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。其实Java并发编程中跟数据库的原子性也类似:即一个操作或者多个操作要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。也可理解为要么所有的指令都执原创 2022-02-24 12:44:34 · 1524 阅读 · 3 评论 -
深度解析Java并发容器【重点】
【重点】深度解析Java并发容器 概要结语 同学们,今天我们一起来深度解析Java当中的并发容器,通过本文的学习,你将了解到Java中有哪些常用的并发容器。概要 前面我们解析了ArrayList集合以及HashMap的源码,其实很多同学都知道在多线程并发情况下,这两个类都不是线程安全的。所以在JDK1.5之前,没有现在的并发容器的概念,常常使用Collections提供的包装接口来将非同步容器转变为同步容器。其原理是通过加上synchronized关键字来修饰方法,我们可以来看下方法: List原创 2022-02-24 10:12:30 · 999 阅读 · 8 评论