并发
文章平均质量分 87
多线程笔记
liang8999
这个作者很懒,什么都没留下…
展开
-
并发集合(二):CopyOnWriteArrayList
在写数据时,先获取Lock锁,然后复制一个副本,添加数据时,是往副本数组中添加数据,最 后再将副本数组赋值给自身array属性,这样可以保证读写分离(读写完全独立),从而提高 读写性能。CopyOnWriteArrayList 是弱一致性的,写操作先操作,但是副本还没落CopyOnWriteArrayList 的 array属性中,此时读操作是无法读取刚写入的数据的。CopyOnWriteArrayList 是基于Lock锁和线程副本的形式来保证线程安全的,原创 2024-09-03 17:32:10 · 359 阅读 · 0 评论 -
并发工具类(二):CyclicBarrier
在 CyclicBarrier 中,每个子任务完成后,子线程调用 CyclicBarrier的await方法。个线程到达屏障点时,屏障点数值就会减1操作,并且线程阻塞在屏障点,当屏。在释放屏障点之后,可以先执行一个任务,然后让唤醒阻塞的线程继续执行后。障点数值变为0时,屏障就会打开,唤醒所有阻塞在屏障点的线程。,即在定义 CyclicBarrier 屏障点数值时,在原有的数值上加1,然后在主线程中执行。然后判断减1后的count是否等于0,若等于0,则唤醒所有阻塞在屏障点的线程,并重置。原创 2024-09-05 16:08:51 · 884 阅读 · 0 评论 -
JUC阻塞队列(一):BlockingQueue 概述
ArrayBlockingQueue 是BlockingQueue的一个实现类,是基于数组实现的阻塞队列,该方法作用也是向 ArrayBlockingQueue 队列添加数据,添加成功返回true,添加失败。若队列为空,该方法不会立即返回,线程会阻塞,直到超过。该方法也是向队列中添加数据;当线程挂起的时候,如果对当前阻塞线程的中断标志位进行设置,此时会抛出异常,当线程挂起的时候,如果对当前阻塞线程的中断标志位进行设置,此时会抛出异常,该方法也是从队列中取数据,若队列为空,则一直阻塞,直到队列中有数据;原创 2024-08-16 15:16:41 · 1001 阅读 · 0 评论 -
JUC阻塞队列(二):LinkedBlockingQueue
该方法功能是删除队列头元素(第一个进入队列的元素),若队列为空,则返回null;该方法作用也是向队列中添加数据,若添加成则返回true,添加失败返回false。该方法功能也是向队列添加数据,若添加失败则会阻塞,若超过了超时时间还没添加成功。该方法是带有超时时间的获取队列的第一个元素;该方法功能也是向队列中添加数据,若添加失败,则一直阻塞,直到队列中有空位可以。该方法功能也是删除并返回队列的第一个元素,若队列为空,则一直阻塞,直到队列。该方法作用是向队列中添加数据,若添加失败,则直接抛出异常;原创 2024-08-19 14:15:24 · 658 阅读 · 0 评论 -
JUC阻塞队列(三):PriorityBlockingQueue
该方法功能是取堆根节点(即queue中第一个数据)数据后把数组queue最后一个数 x “虚拟” 的(假设)放到堆的跟几点(即queue[0]的位置),然后通过循环遍历比较每个节点及其。该方法功能是取堆根节点(即queue中第一个数据)数据后把数组queue最后一个数 x “虚拟” 的(假设)放到堆的跟几点(即queue[0]的位置),然后通过循环遍历比较每个节点及其。指定),则 PriorityBlockingQueue 保存的数据必须是可比较的对象,即。原创 2024-08-20 16:38:37 · 667 阅读 · 0 评论 -
并发工具类(一):CountDownLatch
其中内部类Sync是 AQS 的一个子类,所以Sync也可以。CountDownLatch 的核心属性只有一个,即 sync,Sync 是 CountDownLatch的内部类,countDown() 方法没执行一次,CountDownLatch 计数器的值就会减1,直到计数器的值为。方法,其由AQS各个子类实现,其在 CountDownLatch.Sync 中的实现功能是 将计数器的值。await 方法功能是判断当前 CountDownLatch 的计数器值是否为0,若为0,则直接唤醒阻塞。原创 2024-09-05 10:14:06 · 762 阅读 · 0 评论 -
JUC阻塞队列(五):SynchronousQueue
消费者来配对,则返回false;remove(): 消费者放到 SynchronousQueue 时,若有生产者在等待配对,则立即。offer(E e):生产者在放到SynchronousQueue同时,如果有消费者在等待配对,put(E e) :生产者在放到SynchronousQueue同时,如果有消费者在等待配对,add(E e) :生产者在放到SynchronousQueue同时,如果有消费者在等待配对,poll():消费者放到 SynchronousQueue 时,若有生产者在等待配对,则立即。原创 2024-08-23 16:00:36 · 945 阅读 · 0 评论 -
并发集合:ConcurrentHashMap解析
ConcurrentHashMap 是线程安全的HashMap,但最早的线程安全的HashMap 是 HashTable。put 方法是ConcurrentHashMap 中基本的存储数据的方法,若key不存在,则直接添加,若。putIfAbsent 方法也是存储数据的方法,与put的方法的区别是,若key已经存在,则什么也。该方法是红黑树TreeBin 的方法,功能是根据key的hash值和key从红黑树中获取数据。(即桶中),将数据封装成Node节点以链表的形式保存到该桶中,若桶中的节点个数大于8,原创 2024-09-03 11:08:57 · 909 阅读 · 0 评论 -
JUC阻塞队列(四):DelayQueue
因为 DelayQueue 底层是基于 PriorityQueue 实现的,也就是基于二叉堆实现的,所以。DelayQueue 是一个延迟队列,生产者写入一个数据,这个数据具有被直接消费的延迟时间,DelayQueue 是一个无界的队列,存储数据的数组可以动态扩容,所以生产者不需要关注。二叉堆结构每次获取的是堆顶数据,在比较时,根据延迟时间进行比较,延迟时间剩余端的放。该方法功能是取数据,取堆顶数据,若取不到数据,则直接抛出异常。注意:若堆顶数据的延迟时间还没到达,则取不到数据,也会抛出异常。原创 2024-08-21 17:36:14 · 534 阅读 · 0 评论 -
并发工具类(三):Semaphore
acquire() 和 acquire(int permits) 方法是获取信号量,若获取失败则一直挂起等待,直到获取。Semaphore 的核心属性只有一个Sync 类型的变量,Sync是 Semaphore 的一个内部类继承。2)如果此时 Semaphore 内部的计数器等于0,表示没有可用的许可证,那么当前线程。根据 Semaphore 的特性,只要没有可用的信号量(许可证),则当前线程需要挂起等待,这里我们需要重点关注下 Semaphore 的构造函数,什么时候是公平的,什么时候是非公平的。原创 2024-09-06 16:13:22 · 1045 阅读 · 0 评论 -
并发编程三大特性之可见性
(1)volatile 属性被写:当写一个volatile变量,JMM会将当前线程的CPU缓存的。lock 锁是基于volatile实现的,lock 锁内部进行加锁和释放锁时,会对一个volatile修饰的属。如果对volatile属性进行写操作,CPU会执行带有lock前缀的指令,会将CPU缓存的数据立。其实变量加了volatile就是告诉cpu,对当前变量的读写操作,不允许使用CPU缓存;如果属性被volatile修饰,相当于告诉cpu,对于当前属性的操作,不允许使用CPU。原创 2024-04-07 17:42:19 · 1931 阅读 · 0 评论 -
AQS(一):互斥锁的加锁和锁的释放流程
release方法是AQS中互斥锁 释放锁的入口,在该方法中通过调用子类的tryRelease() 方法。该方法的作用是:线程节点node已经存在于AQS队列中,调用该方法判断 是否将node关联。该方法作用是把 当前线程节点添加到AQS队列中,每次都把新创建的Node节点添加到。该方法作用是 取消AQS阻塞队列中的节点node,使node后续不再进锁资源的竞争。SHARED =共享的节点(共享锁)注意:当前node节点是活跃节点(即持有锁的节点)且node一定是头节点。原创 2024-08-05 16:35:43 · 638 阅读 · 0 评论 -
并发编程三大特性之原子性
如果 ThreadLocal 引用丢失,key因为弱引用会被GC回收掉,如果同时。2)ThreadLocal 本身不存储数据,像是一个工具类,基于ThreadLocal去操作。引用,在GC时,也必须被回收。象失去引用后,如果key的引用是强引用,会导致ThreadLocal对象无法。线程还没有被回收,就会导致内存泄漏,内存中的value无法被回收,同。5)ThreadLocalMap的key是一个弱引用,若引用的特点是:对象即使存在弱。的ThreadLocal,ThreadLocal绑定的是当前线程。原创 2024-04-06 19:53:33 · 938 阅读 · 1 评论 -
java中锁的分类
java中的 ReentrantReadWriteLock有互斥锁也有共享锁,其中写锁是互斥锁,读锁是共享锁。当线程A、B同时去竞争锁资源T,若A成功拿到了锁T,线程B没有拿到锁T,线程B去。当线程A、B同时去竞争锁资源T,若A成功拿到了锁T,线程B没有拿到锁T,线程B去。此时线程C进来了,锁T被A持有,同时线程B在排队,此时线程。2、不可重入锁:当线程A已经拿到了锁S,当线程A再次场次获取锁S,线程A是不可以获取。1、可重入锁:当线程A已经拿到了锁S,当线程A再次场次获取锁S,线程A是可以获取。原创 2024-08-01 16:33:17 · 971 阅读 · 0 评论 -
LockSupport工具类介绍
1)park--unPark 类似于对象锁中的 wait-notify/notifyAll,也是用来阻塞/唤醒 线程,但 wait--notify 只能先wait,后 notify,使用不当的话可能会引起死锁的问题,3)wait -- notify 的调用需要依赖对象,但 park--unPark 不需要依赖对象,只需要。LockSupport提供的是一个许可,如果存在许可,线程在调用park的时候,会立马返回,此时许可也会被消费掉,如果没有许可,则会阻塞。死锁的问题,unpark 可以唤醒指定的线程;原创 2024-08-06 16:41:31 · 194 阅读 · 0 评论 -
java内存模型
有的本地内存(Local Memory,又称 线程内存、CPU内存),在操作的时候把主内存中。在消息传递并发模式里,因为消息的发送必须在消息的接收之前,因此同步是隐士的。注意:JMM是一个抽象的概念,在硬件实体中并不存在,是程序设计层面的东西。关系,即:线程之间的共享变量存放在主内存(Main Memory)中,每个线程都有一个私。即JMM定义了线程与主内存之间的抽象。在共享内存的并发模型里,线程之间共享程序的公共状态,通过读-写。注意,把线程内存的变量刷新到主内存这一步操作不一定是及时的,可能其他线程。原创 2024-04-06 11:38:33 · 284 阅读 · 1 评论 -
AQS(二):共享锁的获取和释放
享锁成功,若tryAcquireShared() 获取锁失败,则调用 doAcquireShared() 方法将当前线程。该方法用于获取共享锁(读锁),在方法中先调用 tryAcquireShared() 方法判断是否获取共。是否成功,若子类释放锁成功,则调用方法 doReleaseShared() 去释放AQS中的当前共享。该方法作用是释放共享锁,通过调用子类的tryReleaseShared() 来判断子类具体的锁释放。该方法作用是:更新AQS阻塞队列的头节点(将当前获取锁的线程节点设置为头节点),原创 2024-08-06 15:24:27 · 742 阅读 · 0 评论 -
synchronized锁升级过程
synchronized 上锁,其实锁信息是加在对象头中的 markdown,对象中的前四个字节表示markdown;的方式,尽可能的把自身的LR设置到 markdown中,若设置成功,makrdown会有。有多个线程竞争synchronized锁时,先把偏向锁撤销,通过自旋的竞争(自旋锁)升级。不一定,偏向锁只有在单线程环境中效率最高;偏向锁每重入一次,在线程栈中都会生成一个LR,但这个LR的值等于NULL,重入次数。轻量级锁重入次数与偏向锁差不多,锁重入次数都是记录在线程栈的LR重,每重入一次也是。原创 2024-03-19 17:36:59 · 2772 阅读 · 0 评论