
多线程
文章平均质量分 64
xiaoye-2018
不为明天而烦恼、不为昨天而叹息、只为今天更美好。
展开
-
小白系列--ReentrantReadWriteLock源码学习
ReentrantReadWriteLock 简介 在并发编程中,为了确保数据的安全性,我们常常采用synchronized来对代码段进行加锁,防止其他线程同时对数据进行修改,从而导致数据不一致的问题,大多数人都知道synchronized是一个重量级的锁(JDK 6 之前),在线程切换时OS会发生用户态到内核态切换,因此使用他来加锁,在线程数量较多的情况下会严重影响程序的性能,因此后面JDK引入了Java层面加锁的机制,即Java.util.concurrent包下的类 ReentrantReadWri原创 2021-04-21 16:25:56 · 123 阅读 · 0 评论 -
小白系列--ReentrantLock源码学习
ReentrantLock 实现Lock接口,Lock接口只是定义了一些加锁,解锁的一些抽象方法 有一个静态的抽象类Sync,继承AQS, 静态内部类FairSync、NoFairSync 继承Sync , 默认为非公平锁 使用比较简单,如下面一样,作为一名有追求的程序员,肯定不能局限于表面,继续研究底层源码 public void testLock() { ReentrantLock lock = new ReentrantLock(); lock.lock(); try {原创 2021-04-21 16:24:46 · 104 阅读 · 0 评论 -
AQS-Condition源码学习
Condition 在使用synchronized加锁时,当线程调用wait方法后,会将线程放入等待队列中,其他线程调用notify(或notifyAll)方法后才会将当前线程唤醒,进入同步队列,而notifyAll是将等待队列中的所有线程都放入同步队列中,notify是挑选其中一个线程进入同步队列 这种原始的通知方法不能够指定通知某个线程,为了达到精准通知,因此JDK5后引入了AQS,而AQS中包含一个ConditionObject的内部类(我们经常说的Condition) Condition是由原创 2021-04-21 16:18:36 · 127 阅读 · 0 评论 -
小白学java底层源码-----TreeMap
TreeMap 基于红黑树实现,可以参考HashMap中的红黑树实现方式 通过实现Comparable接口对key进行自然排序,或则创建对象时提供Comparator get、remove、put、containsKey方法的时间复杂度都是logN 本文只对TreeMap作一个简单的分析,节点的删除、修改、添加、节点调整等具体操作请参考HashMap中源码 属性及构造: // TreeMap比较器,如果为null,那么将对key进行自然排序 private final Comparator<?原创 2021-04-11 10:21:31 · 129 阅读 · 0 评论 -
多线程之小白系列
文章参考B站up狂神说JAVA、《Java并发编程》 1. 线程实现的三种方式 1. 继承Thread 自定义类继承Thread 重写run()方法 调用start()开启线程 public class ThreadDemo extends Thread{ @Override public void run() { for (int i = 0; i < 200; i++) { System.out.println("我在学习" + i); } } .原创 2021-04-08 22:41:06 · 318 阅读 · 2 评论 -
小白学java底层源码-----AQS
简介 AQS全称AbstractQueueSynchronizer,基于FIFO等待对列实现的一个同步器框架,JUC包中的很多类都基础自AQS,比如:ReentrantLock,ReentrantReadWriteLock、CountDownLatch等,AQS是在Java语言层面实现锁的机制,避免了用户态跟内核态之间的切换,我们知道Synchronized属于操作系统层面,在JDK5之前,使用synchronized对程序进行加锁,对应操作系统的MUTEX实现,在线程竞争激烈的环境下会造成频繁的上下文切换原创 2021-04-08 22:37:08 · 100 阅读 · 0 评论 -
小白学java底层源码-----PriorityQueue
Priority Queue JDK5开始引入, 能够根据对象的优先级来进行排序,要求对象实现Comparable或Comparator接口中的比较方法,底层采用堆来实现。 基本介绍: 根据优先级来排列的队列,存储的对象一定要实现Comparable接口,否则将抛出异常 底层实际上也是通过数组来进行存储数据的, 大小无限(官方文档写的,哈哈) 实现了Collection和Iterator接口,通过Iterator遍历数据时并不保证有序的,如果要有序输出,可以通过Arrays.sort(pq.toArr原创 2021-02-01 23:57:35 · 297 阅读 · 3 评论 -
小白系列-----ArrayBlockingQueue
ArrayBlockingQueue 基于数组实现了阻塞队列 必须指定空间大小,可以设置生产、消费线程等待顺序的公平性、默认非公平 使用公平获取资源将会降低吞吐量,但是可以避免饥饿 基本属性&方法: /** The queued items */ final Object[] items; /** items index for next take, poll, peek or remove */ int takeIndex; /** items index for next put, of原创 2021-05-21 19:52:24 · 131 阅读 · 0 评论 -
小白系列----LinkedBlockingQueue
LinkedBlockingQueue 基于链表实现的阻塞队列,默认长度Integer.MAX_VALUE 吞吐量通常比基于数组实现的高,但在同步应用的场景下性能更难预测 插入元素大致逻辑: 成员变量 // 存储节点的信息 static class Node<E> { E item; Node<E> next; Node(E x) { item = x; } } // 存储元素的空间大小,默认Integer.MAX_VALUE原创 2021-05-21 19:51:36 · 143 阅读 · 0 评论 -
小白系列----DelayQueue源码剖析
DelayQueue 介绍 继承关系如下: DelayQueue是一个支持获取元素的无界阻塞队列。队列使用PriorityQueue来实现,关于PriorityQueue的方法见另一篇文章 小白学PriorityQueue ,队列中的元素必须实现Delayed接口,实现getDelay方法,该方法返回指定的延迟时间,即该元素存活多久后可以从队列中提取元素 举个例子: // 参考最下的链接 public class DelayQueueTest1 { private static DelayQ原创 2021-05-17 22:48:22 · 190 阅读 · 0 评论 -
JDK8 ConcurrentHashMap computeIfAbsent bug分析
前段时间准备研究一波Mybatis,代码下载到IDEA,一路Debug走了一遍,头已经绕晕,准备放弃突然看到一些英文 上面写了啥bug 啥的,于是打开链接看了下,大概就是说的computeIfAbsent 方法,如果key存在的情况下也会加锁,会影响性能,后面又百度了下,发现还有其他bug 在写本文前,也看了些网上的文章,大概就是说的是在调用computeIfAbsent(key, …)方法时,正好其他线程需要在key对应位置插入结点,因为computeIfAbsent方法将位置设置了Reservati原创 2021-05-17 22:32:08 · 1852 阅读 · 0 评论