![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java并发编程
文章平均质量分 73
Java并发讲解
张孟浩_jay
分享Java后端、MySQL、数据结构、计算机基础、算法、并发编程技术!欢迎朋友们交流关注,共同进步!
展开
-
线程池分类
Java中Executors提供了5种线程池,本文就说一下这五种线程池。阅读本文之前需要了解以下ThreadPoolExecutor的原理,可以看一下我之前写的一篇文章Java线程池ThreadPoolExecutor详解1、newCachedThreadPool()public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE,原创 2021-09-07 21:45:35 · 277 阅读 · 0 评论 -
Java中NIO详解
NIO是当前Java中最流行的IO方式,大名鼎鼎的网络框架Netty就是基于NIO的。本文将仔细介绍NIO的工作方式。NIO简介NIO的底层原理就是对IO进行多路复用,对IO多路复用不太了解的可以看我之前写的文章Linux中网络IO模型详解通过多路复用可以在一个线程中监听多个连接,节省了线程资源。NIO详解NIO中有三个核心:1、Buffer简介Buffer就是缓冲池。Buffer和Channel配合使用。1、将Channel中的数据读取到Buffer中。2、将Buffer中的数据写入到C原创 2021-09-04 14:51:14 · 1834 阅读 · 2 评论 -
LockSupport.park unpark 和wait、notify的区别
66原创 2021-08-31 20:16:46 · 1026 阅读 · 1 评论 -
ConcurrentSkipListMap
ConcurrentSkipListMap简介ConcurrentSkipListMap是基于SkipList,也就是跳表实现的同步Map。跳表是类似于B+数的一种数据结构,查找和修改的性能十分优秀。具体实现原理我们过几天再详细说,先挖个坑原创 2021-08-31 17:29:04 · 135 阅读 · 1 评论 -
PriorityBlockingQueue源码详解
PriorityBlockingQueue简介PriorityBlockingQueue是PriorityQueue的并发容器,是线程安全的。PriorityQueue是一个完全二叉树,对每个节点都进行编号。如果从1开始编号的话,parent和节点有一定的关系。parent.id = child.id / 2;leftChild.id = parent.id * 2 ;rightChild.id = parent.id * 2 + 1;由于这个特性,所以PriorityQueue可以用数组来原创 2021-08-31 17:13:47 · 244 阅读 · 1 评论 -
ArrayBlockingQueue源码详解
ArrayBlockingQueue简介上篇文章我们说了LinkedBlockingQueue,ArrayBlockingQueue相较于LinkedBlockingQueue,就是ArrayBlockingQueue是基于数组的。其实现的功能和LinkedBlockingQueue一样。ArrayBlockingQueue源码解析主要属性//数据数组final Object[] items;//头节点下标int takeIndex;//尾节点下标int putIndex;//元素原创 2021-08-31 16:02:16 · 356 阅读 · 1 评论 -
LinkedBlockingQueue源码详解
LinkedBlockingQueue简介LinkedBlockingQueue是LinkedList对应的并发版本,是基于链表的。通过名字中带有Blocking就可以看出当入队和出队不满足条件的时候,会阻塞如果想彻底了解LinkedBlockingQueue的话,需要了解ReentrantLock的相关知识,如果对ReentrantLock不太了解的话,建议看一下我之前写的关于ReentrantLock的文章ReentrantLock源码详解LinkedBlockingQueue源码解析主要变量原创 2021-08-31 15:07:22 · 169 阅读 · 1 评论 -
JDK1.7中HashMap并发成环的原因
JDK1.7中HashMap存在并发成环的问题。问题发生在扩容搬运的时候,具体代码如下。void transfer(Entry[] newTable, boolean rehash) { int newCapacity = newTable.length; //table是旧table,也就是扩容前的table for (Entry<K,V> e : table) { //e为槽位的头节点,通过头节点遍历槽位 while(null !=原创 2021-08-31 12:11:30 · 334 阅读 · 1 评论 -
ConcurrentHashMap源码详解
ConcurrentHashMap简介ConcurrentHashMap是HashMap的同步容器,是线程安全的。ConcurrentHashMap通过CAS和Synchronized来实现线程安全!ConcurrentHashMap源码详解public V put(K key, V value) { return putVal(key, value, false);}static final int spread(int h) { //HASH_BITS = 0x7fffff原创 2021-08-30 22:37:16 · 2207 阅读 · 1 评论 -
CopyOnWriteArrayList源码解析
CopyOnWriteArrayList简介CopyOnWriteArrayList是ArrayList的并发容器。写操作:通过名字就可以看出来其原理。CopyOnWriteArrayList会将对象数组拷贝到新数组中,当写的时候会写在新数组上,然后将CopyOnWriteArrayList的对象数组替换成新数组。读操作:读操作不会加任何锁了解了写操作和读操作的做法后,我们发现CopyOnWriteArrayList适合于写少读多的场景。CopyOnWriteArrayList源码解析主要属原创 2021-08-28 18:36:26 · 131 阅读 · 1 评论 -
Java中并发容器详解
Java1.5之前,没有所谓的直接的同步容器,只能通过Collections提供了包装接口来将非同步容器变为同步容器,其原理就是通过synchronized关键字来修饰方法。方法如下:List list = Collections.synchronizedList(new ArrayList<>());Set set = Collections.synchronizedSet(new HashSet<>());Map map = Collections.synchronized原创 2021-08-28 17:30:37 · 218 阅读 · 1 评论 -
ForkJoinPool并行任务
ForkJoinPool简介ForkJoinPool是Java中提供了一个线程池,特点是用来执行分治任务。主题思想是将大任务分解为小任务,然后继续将小任务分解,直至能够直接解决为止,然后再依次将任务的结果合并。类似于单机版的MapReduce。ForkJoinPool用法示例public class TestForkJoin { public static void main(String[] args) throws ExecutionException, InterruptedExce原创 2021-08-28 16:38:26 · 407 阅读 · 3 评论 -
CompletionService详解
当我们有批量执行多个异步任务的业务,并且需要调用get()获取执行结果的时候,我们写的代码一般如下:Future f1 = excutor.submit(c1);f1.get();Future f2 = excutor.submit(c2);f2.get();f1.get()在获取成功之前会被阻塞,会阻塞c2的执行,严重降低了效率。这时我们可以通过CompletionService来解决这一问题!CompletionService结构CompletionSerive接口有一个实现类Exe原创 2021-08-27 23:08:14 · 6978 阅读 · 2 评论 -
CompletableFuture详解
在阅读这篇文章之前,需要一点lambda知识,如果不太清楚的话,可以看我之前写的Java8中lambda详解CompletableFuture的出现原因我们上篇文章说了Future和FutureTask。但是Future有一个缺点,调用线程需要使用future.get()来获取调用结果,这个方法是阻塞的,也就说调用线程会被阻塞。而CompeletableFuture提供了回调方法来解决这一问题。当任务执行完之后,会通知调用线程来执行回调方法。而在调用回调方法之前,调用线程可以执行其他任务,是非阻塞的。原创 2021-08-27 21:36:15 · 3979 阅读 · 1 评论 -
ThreadPoolExecutor之Future、FutureTask源码解析
1、Future的出现原因我们在Java线程池ThreadPoolExecutor详解中利用execute(Runnable r)方法来执行任务,但是有一个缺点,就是无法执行带有返回值的任务。所以引入了Future来解决这个问题。2、Future详解Future中有5个方法:1、cancel():取消任务2、isCancelled():任务是否取消成功3、isDone():任务是否完成了4、get():获取返回值,阻塞5、get(long count,TimeUnit):按照count个原创 2021-08-26 22:46:21 · 841 阅读 · 1 评论 -
Java线程池ThreadPoolExecutor详解
线程池出现的原因为什么需要线程池呢?我们直接通过new Thread创建线程不就好了吗?Thread对象和普通的对象不一样,普通的对象在JVM中划分一块内存区域将数据存到里面就行了,而Thread需要调用操作系统的API来为Thread分配资源,需要从用户态切换到内核态,十分消耗资源,所以Thead是一个重量级对象,要避免线程频繁的创建和销毁,所以就引入了线程池!线程池实例//任务队列BlockingQueue queue = new LinkedBlockingQueue(10);Threa原创 2021-08-26 20:14:31 · 4453 阅读 · 1 评论 -
Java原子类Atomic详解
解决并发的线程安全问题有两种方式:1、加锁2、原子类原创 2021-08-25 23:00:07 · 10642 阅读 · 2 评论 -
StampedLock详解
StampedLock简介StampedLock是比ReentrantReadWriteLock更快的一种锁,支持乐观读、悲观读锁和写锁。和ReentrantReadWriteLock不同的是,StampedLock支持多个线程申请乐观读的同时,还允许一个线程申请写锁。StampedLock的底层并不是基于AQS的。StampedLock示例 class Point { private double x, y; private final StampedLock sl = new S原创 2021-08-23 18:02:56 · 3921 阅读 · 8 评论 -
ReentrantReadWriteLock源码详解
读写锁我们都不陌生,多个线程可以同时拥有读锁,而同时只有一个线程拥有写锁,并且写锁和读锁是冲突的。ReentrantReadWriteLock就是依据AQS实现的一个读写锁。ReentrantReadWriteLock原创 2021-08-22 23:25:07 · 233 阅读 · 1 评论 -
Semaphore源码详解
semaphore简介semaphore就是我们常说的信号量,本质就是基于AQS的一个共享锁。原创 2021-08-22 09:50:23 · 335 阅读 · 3 评论 -
CyclicBarrier源码详解
CyclicBarrier简介CyclicBarrier也是一种线程同步工具,用于多个线程之间的同步,也是适用于一个线程等待多个线程。和CountDownLatch相比,CyclicBarrier有多个改进:1、CyclicBarrier可以循环利用2、CyclicBarrier中的线程的同步更加严谨。CountDownLatch中的线程在countDown()后就会执行代码,而CyclicBarrier中的线程会一直阻塞,直到被同步的方法调用,所以说CyclicBarrier中的线程的同步程度更高。原创 2021-08-20 22:46:09 · 221 阅读 · 1 评论 -
CountDownLatch源码分析
CountDownLatch简介简介:CountDownLatch是基于AQS共享锁的一个锁工具,用来解决一个线程必须等待多个线程完成后才运行的场景,count就是代表线程的个数。CountDownLatch基于AQS的共享锁,如果你对这块知识还不了解,可以看我之前写的文章:AQS源码详细分析,让你掌握AQS原理,独占锁、共享锁、ConditioCountDownLatch举例package juc;import java.util.concurrent.CountDownLatch;pub原创 2021-08-20 21:11:57 · 157 阅读 · 1 评论 -
ReentrantLock源码详解
ReentrantLock是Java中常用的锁工具,今天我们来了解一下。本篇文章设计到AQS,如果了解到不太清楚的话,可以看我之前写的文章AQS源码详细分析,让你掌握AQS原理,独占锁、共享锁、ConditionReentrantLock概述ReentrantLock是基于我们之前讲过的AQS构造的。ReentrantLock是一个独占锁,提供了非公平锁和公平锁两种模式。我们首先说下公平锁和非公平锁的区别:**公平锁:**线程在请求锁的时候,依次入队,严格按照先来后到的顺序分配锁。**非公平锁:*原创 2021-08-20 20:03:39 · 290 阅读 · 1 评论 -
AQS源码详细分析,让你掌握AQS原理,独占锁、共享锁、Condition
这篇文章我们来说下AQS。1、AQS简介AQS全称为AbstractQueuedSynchronizer,是ReentrantLock、Semaphore、CountDownLatch等并发工具的基础类。AQS与Synchronized有一个区别是:Synchronized中所有阻塞的线程都集中到了一个队列中,当有线程释放锁的时候,会将所有线程都唤醒。因为有些线程需要的条件并不满足,但是也被唤醒了,这种线程唤醒了即使得到了锁也无法执行,这就会浪费了资源。AQS相较于Synchronized内置了多原创 2021-08-19 21:55:29 · 744 阅读 · 3 评论 -
第三篇:Java中Synchronized原理详解以及锁的升级
Java为了解决并发的原子性,提供了以下两个解决方案:1、Synchronized关键字2、Lock管程这篇文章我们先说一下Synchronized关键字,Lock管程等着下篇文章再说。1、Synchronized的三种用法package juc;public class TestSyn { static int x = 0; int y = 0; public static void main(String[] args) throws InterruptedExc原创 2021-08-16 22:43:52 · 373 阅读 · 3 评论 -
第二篇:Happens-Before
编译器会对程序进行优化,会调整代码的顺序。如果贸然调整顺序的话,可能会引发线程不安全!Java指定了Happens-Before六条规则,要求编译器必须满足Happens-Before原则,来控制数据的内存可见性。Happens-Before就是在什么之前发生的意思。1、A语句 happens-before B语句,那么在执行B语句的时候,A语句执行的结果是可见的。x = 40;y = 60;当执行y = 60的时候,之前对x的更改为40的操作是可见的。2、volatile写操作happens原创 2021-08-14 22:50:00 · 190 阅读 · 1 评论 -
第一篇:Java并发编程的三大特性:原子性、可见性、有序性
并发是什么呢?并发指的是Java中有多线程并发运行。为什么会有并发?因为一个线程在执行的过程中不仅会用到cpu资源,还会用到IO,也就是输入输出。IO的速度远远比不上CPU的运算速度。如果线程在IO的时候,不放弃CPU资源,就会导致CPU空闲,以至于CPU的利用率十分低下。所以就引入了多线程,当一个线程要请求IO的时候,会放弃cpu资源。这个时候,其他线程可以使用cpu。这就提高了cpu的利用率。虽然线程之间的切换有额外的资源消耗,但是带来的回报更大。所以多线程是主流。Java并发编程有三大特性:原创 2021-08-14 21:32:14 · 353 阅读 · 1 评论