
多线程高并发专题
文章平均质量分 94
多线程高并发,入门到精通
胡尚
只要学不死就往死里学
展开
-
并发原子性、可见性、有序性与JMM内存模型
java的线程之间通信是由java内存模型(Java Memory Model,简称JMM)控制。它来决定一个线程对共享变量的写入何时对另一个线程可见。JMM模型是屏蔽底层各种处理器的差异的,因为java是跨平台的,不同的处理器对内存屏障的支持也是不一样的。线程之间的数据交互,JMM内存模型中有一块主内存空间,各个线程还有自己的工作内存。在主内存读取变量的时候是拷贝一份变量的副本到自己的工作内存,之后的读取都是先从之间的工作内存中找。修改操作会先更新工作内存区中的值,然后在写回主内存中。原创 2023-04-09 20:18:22 · 562 阅读 · 0 评论 -
线程池ThreadPoolExecutor原理
刚开始线程池中是没有线程的,如果来了任务那么就直接去创建线程处理,如果核心线程处理完任务了,但是线程数量还没有达到核心线程数,此时来了任务也还是会去创建新线程处理,直到线程数量达到了核心线程数。我们首先要计算出每个任务的执行耗时,然后再看所有核心线程数去拿队列中的最后一个任务的耗时,业务能否接收,如果能接收那么队列长度的设置就可以。线程数 >= 核心线程数后,再来新任务就会直接放入阻塞队列中,并唤醒等待的线程去处理,当队列中没有任务了那么线程就阻塞。创建线程池时,线程池中是不会创建线程的。原创 2023-04-07 16:34:31 · 656 阅读 · 0 评论 -
深入学习java线程、线程间的通信与协调、CompleteableFuture使用案例
总结计算可以由FutureConsumer或者Runnable接口中的applyaccept或者run等方法表示。计算的执行主要有以下默认执行使用默认的的异步执行提供者异步执行。这些方法名使用这种格式表示。使用Executor提供者异步执行。这些方法同样也是这种格式,但是会增加一个Executor参数。原创 2023-03-31 20:46:21 · 1043 阅读 · 0 评论 -
线程池ThreadPoolExecutor源码
不过还有一个种情况,就是目前所有工作线程都在执行任务,但是阻塞队列中还有剩余任务,那逻辑应该就是这些工作线程执行完当前任务后要继续执行队列中的剩余任务,但是根据我们看到的shutdown方法的逻辑,发现这些工作线程在执行完当前任务后,就会释放锁,那就可能会被中断掉,那队列中剩余的任务怎么办呢?当线程池状态为SHUTDOWN时,如果阻塞队列中的任务执行完了那么也淘汰所有线程,直接返回null就是淘汰退出线程,因为。0,就表示线程池的状态为RUNNING,线程池中目前在工作的线程有10个。原创 2023-04-07 20:57:23 · 780 阅读 · 0 评论 -
多线程并发安全问题
是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁。死锁是必然发生在多操作者(M>=2 个)争夺多个资源(N>=2 个,且 N原创 2023-04-01 18:49:09 · 660 阅读 · 0 评论 -
阻塞队列BlockingQueue
ArrayBlockingQueue它队列使用的数据结构是双指针的环形数组,入队出队是基于生产者消费者模型实现的,它入队和出队使用的是同一把锁。基本使用//向队列中添加元素 Object object = queue . take();//从队列中取出元素其实// 生产者,把方法的入参往队列中存,队列是一个环形数组 public void put(Object x) throws InterruptedException {try {原创 2023-04-06 19:49:35 · 406 阅读 · 0 评论 -
ReentrantReadWriteLock读写锁底层实现、StampLock详解
适用于读多写少的场景,特点是读读不互斥,读写与写写互斥。ReentrantReadWriteLock它有个潜在的问题:如果有线程正在读,写线程需要等待读线程释放锁后才能获取写锁,即读的过程中不允许写,这是一种悲观的读锁。Java 8引入了新的读写锁:StampedLock读的过程中也允许获取写锁后写入!在原先读写锁的基础上新增了一种叫乐观读(Optimistic Reading)的模式。该模式并不会加锁,所以不会阻塞线程,会有更高的吞吐量和更高的性能。原创 2023-04-05 16:59:05 · 544 阅读 · 0 评论 -
导致JVM内存泄露的ThreadLocal详解
它的实现,它类似于jdk1.7版本的hashmap,底层存储的是一个Entry对象的数组,初始容量也是16,存值时先用hash结果和数组长度取余得到数组下标位置,然后判断是否产生了hash冲突,然后使用。为了提高性能,才没有采用加锁的方式,而是将map和各个线程thread对象进行关联,这样就避免了产生线程安全问题,也避免了加锁,提高了性能。而且如果是多个线程保存一个变量的副本,一个静态的ThreadLocal也足够了,因为它是作为多个map中的key存在的。它是使用的线性探测再散列法,如下所示。原创 2023-04-01 13:37:44 · 360 阅读 · 0 评论 -
并发容器(Map、List、Set)原理
是java线程安全的哈希表。JDK1.8之前采用的分段锁,JDK1.8时采用的循环CAS+synchronized来实现的。官方的解释是:分段锁的锁对象需要占用更多内存空间、提高GC效率用的比较少,了解即可ConcurrentSkipListMap 是 Java 中的一种线程安全、基于跳表实现的有序映射(Map)数据结构。它是对 TreeMap 的并发实现,支持高并发读写操作。ConcurrentSkipListMap适用于需要高并发性能、支持有序性。原创 2023-04-06 15:22:38 · 730 阅读 · 0 评论 -
CAS&Atomic 原子操作详解
Mysql事务中的原子性就是一个事务中执行的多条sql,要么同时成功,要么同时失败,他们不可拆分。并发中的原子操作也一样,多个线程中,站在线程A的角度看线程B的操作,线程B的操作就是一个原子的;站在线程B的角度看线程A,线程A的操作是原子的。一整个操作要么全部执行完了,要么就没有执行,中间不能拆分。那么要怎么实现原子性嘞?可以使用synchronized锁来保证一段代码的原子性,但是加锁影响性能,甚至还有死锁方面的问题需要考虑。原创 2023-04-01 17:16:46 · 524 阅读 · 0 评论 -
ForkJoinPool线程池工作原理
归并排序(Merge Sort)是一种基于分治思想的排序算法。归并排序的基本思想是将一个大数组分成两个相等大小的子数组,对每个子数组分别进行排序,然后将两个子数组合并成一个有序的大数组。因为常常使用递归实现(由先拆分后合并的性质决定的),所以我们称其为归并排序。归并排序的时间复杂度为O(nlogn),空间复杂度为O(n),其中n为数组的长度。分治思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。原创 2023-04-08 19:04:43 · 1116 阅读 · 0 评论 -
Synchronized原理总结
MonitorSynchronized的实现是基于Monitor的,而Monitor是基于管程的MESA模型,ObjectMonitor数据结构,三个队列,等待唤醒机制基于Object对象中的方法对象的内存布局锁的状态信息是标记在对象头的Mark Word中的。一个对象由对象头、实例数据、对齐填充三部分组成。对象头由Mark Word、Klass point、数组长度组成。无锁状态下Mark Word存储的是对象的hash值、gc分代年龄、偏向锁标识位0、锁标识01。原创 2023-04-14 17:55:41 · 578 阅读 · 0 评论 -
java并发基本概念、线程启动终止
cpu调度中我们知道cpu是频繁切换不同的线程执行的,线程在使用cpu执行时会使用cpu的寄存器与程序计数器的,如果出现了线程切换,那么cpu就会把当前线程在寄存器与程序计数器中的上下文数据拷贝到内存中去,然后再执行另一个的线程,此时会从内存中把另一个线程的上下文在cpu寄存器中进行恢复。这种情况下,使用中断会更好,因为,方法如果被调用则立刻强制停止该线程的执行,这种方式本身就是不安全的,比如正在往磁盘中写一个文件,强制终止线程运行后那么连文件的结束符都不会写,就造成了文件损坏。原创 2023-03-30 21:01:50 · 499 阅读 · 0 评论 -
JUC并发工具类
可中断可选择设置公平锁可以设置超时时间支持多个条件变量解决多线程竞争资源的问题,例如多个线程同时对同一个数据库进行写操作,可以使用ReentrantLock保证每次只有一个线程能够写入。实现多线程任务的顺序执行,例如在一个线程执行完某个任务后,再让另一个线程执行任务。实现多线程等待/通知机制,例如在某个线程执行完某个任务后,通知其他线程继续执行任务。ReentrantLock具体的引用场景如下:解决多线程之间资源竞争问题。原创 2023-04-03 18:54:17 · 677 阅读 · 0 评论 -
synchronized原理、偏向锁、轻量级锁、重量级锁、锁升级
偏向锁是一种加锁操作的优化机制。经过研究发现大部分情况下是不存在锁竞争,一直都是一个线程去获取锁,因此为了消除在无竞争情况下重入锁(CAS操作)的开销,而引入了偏向锁。对于没有竞争的场合,偏向锁有很好的优化效果。JVM1.6默认开启偏向锁。新创建一个对象,此时给对象的Mark Word中的ThreadID为0,说明该对象处于可偏向但未偏向任何线程,也叫作匿名偏向状态。原创 2023-04-13 19:27:43 · 1380 阅读 · 0 评论 -
CPU缓存架构+Disruptor内存队列
cpu与内存的交互数据之间,有一个高速缓存层。有些处理器有3层缓冲,有些处理器有4层缓存当下CPU都是有多核,每核cpu都有一份自己的高速缓存内存中的数据读取到高速缓存中每次读取的数据至少是一次缓存行64字节。原创 2023-04-12 15:30:59 · 557 阅读 · 0 评论 -
AQS独占锁、Reentrantlock源码底层实现
AQS的全程:AbstractQueuedSynchronizer包中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列、条件队列、独占获取、共享获取等,而这些行为的抽象就是基于(简称AQS)实现的,AQS是一个抽象同步框架,可以用来实现一个依赖状态的同步器。JDK中提供的大多数的同步器如Lock, Latch, Barrier等,都是基于AQS框架来实现的阻塞等待队列共享/独占公平/非公平可重入允许中断同步等待队列: 主要用于维护获取锁失败时入队的线程。原创 2023-04-04 18:50:29 · 794 阅读 · 0 评论