【HikariCP】【ConcurrentBag】源码学习

八、HikariCP 源码分析之 ConcurrentBag 一 它是真正的保存所有的连接的地方,它是一个CopyOnWriteArrayList,在写入的时候会先复制一个 sharedList2,然后修改这个新的 sharedList2,最后将变量地址指向新的sharedList2,不是直接写入当前的sharedList,典型的空间换时间的一个做法,可以避免写入前要锁住sharedList,从而导致降低性能。生意火爆,有一天店里没车了,你去仓库提车,仓库管理员说:仓库也没车了,天通苑的连锁店里有闲着的,你去那里提吧,于是你把天通苑连锁店的车借走了。 阅读详情

Hikari目前已经是springboot的默认数据库连接池,并且以高效和轻量著称,因为代码量比较少,所以可以阅读一下,学习一下,github地址:HikariCP

ConcurrentBag

这个是HikariCP的核心功能类,作者在注释中也详细说明了这个类的作用

/**
 * This is a specialized concurrent bag that achieves superior performance
 * to LinkedBlockingQueue and LinkedTransferQueue for the purposes of a
 * connection pool.  It uses ThreadLocal storage when possible to avoid
 * locks, but resorts to scanning a common collection if there are no
 * available items in the ThreadLocal list.  Not-in-use items in the
 * ThreadLocal lists can be "stolen" when the borrowing thread has none
 * of its own.  It is a "lock-less" implementation using a specialized
 * AbstractQueuedLongSynchronizer to manage cross-thread signaling.
 *
 * Note that items that are "borrowed" from the bag are not actually
 * removed from any collection, so garbage collection will not occur
 * even if the reference is abandoned.  Thus care must be taken to
 * "requite" borrowed objects otherwise a memory leak will result.  Only
 * the "remove" method can completely remove an object from the bag.
 *
 * @author Brett Wooldridge
 *
 * @param <T> the templated type to store in the bag
 */
public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseable

翻译能力有限,借助谷歌翻译,大致意思如下:

这是一个专门的并发包,可以为连接池实现LinkedBlockingQueue和LinkedTransferQueue的卓越性能。 它尽可能使用ThreadLocal存储来避免锁定,但如果ThreadLocal列表中没有可用的项目,则会使用它来扫描公共集合。 当借用线程没有自己的东西时,ThreadLocal列表中的未使用项可能被“窃取”。 它是一个“无锁”实现,使用专门的AbstractQueuedLongSynchronizer来管理跨线程信令。

请注意,从包中“借用”的项目实际上并未从任何集合中删除,因此即使放弃引用也不会发生垃圾收集。 因此,必须小心“重新”“借用”借来的对象,否则将导致内存泄漏。 只有“删除”方法才能从包中完全删除对象。

我对这个类的理解就是在多线程的并发场景中,通过自己封装的类,在保证线程安全的情况下维护连接池的安全和高效,数据结构比LinkedBlockingQueue和LinkedTransferQueue这两个queue要高效。

成员变量

  • private final CopyOnWriteArrayList sharedList;

这个成员变量首先要注意到的是它是CopyOnWriteArrayList类型的,这个类型是Java并发包中的类,主要就是解决ArrayList在多线程读写场景中会出现的ConcurrentModificationException。ArrayList在内部维护了一个modCount修改次数的成员变量,如果在写的过程中多个线程同时进行修改,那么当前的修改次数和维护的修改次数可能会不一致导致抛出了这个异常。

所以为了避免这个情况,CopyOnWriteArrayList这个类是这么处理的:读是没有影响的,但是如果要往集合中写元素,那么首先会复制出一个当前List的copy,然后在这个copy中添加这个元素,最后把原来List的地址引用指向这个copy。如果在复制的过程中有线程去读取,那么它读到的是原来的集合中的值。这里因为涉及到集合的复制,所以这种一般是用于集合元素比较稳定,基本不会发生写入的情况。如果元素一直在变化,那么在大数据量的情况下复制的开销是很大的。具体的详情可以推荐这个博客查看CopyOnWriteArrayList的原理和使用方法

回到这个成员变量这个是共享元素的集合。这个元素必须是IConcurrentBagEntry的实例,在hikari中就是封装了数据库连接的分装类,也就是连接

  • private final boolean weakThreadLocals;

是否是弱引用ThreadLocal

  • private final ThreadLocal<List> threadList;

线程持有的成员变量是一个List的借用元素集合

  • private final IBagStateListener listener;

包状态监听器接口

  • private final AtomicInteger waiters;

原子类,等待者数量

  • private volatile boolean closed;

volatile类型,并发包是否关闭

  • private final SynchronousQueue handoffQueue;

这个SynchronousQueue是Java并发包中的,大致的作用是它是一个只有容量1的队列,当生产者生产完放入元素后就会阻塞,直到消费者将该元素取出消费。这样做保证了消息的一对一传递。网上随便一搜有很多这个类的说明。

内部接口

  • IConcurrentBagEntry
public interface IConcurrentBagEntry
{
  int STATE_NOT_IN_USE = 0;
  int STATE_IN_USE = 1;
  int STATE_REMOVED = -1;
  int STATE_RESERVED = -2;

  boolean compareAndSet(int expectState, int newState);
  void setState(int newState);
  int getState();
}

共享元素需要实现的就是这个接口,这个接口定义了四种状态,还有设置状态、获取状态和设置的状态和想要的状态是否一致三个方法

  • IBagStateListener
public interface IBagStateListener
{
  void addBagItem(int waiting);
}

这个监听器接口只有一个方法是增加元素

构造方法

public ConcurrentBag(final IBagStateListener listener)
{
  this.listener = listener;
  this.weakThreadLocals = useWeakThreadLocals();

  this.handoffQueue = new SynchronousQueue<>(true);
  this.waiters = new AtomicInteger();
  this.sharedList = new CopyOnWriteArrayList<>();
  if (weakThreadLocals) {
     this.threadList = ThreadLocal.withInitial(() -> new ArrayList<>(16));
  }
  else {
     this.threadList = ThreadLocal.withInitial(() -> new FastList<>(IConcurrentBagEntry.class, 16));
  }
}

构造器传入一个监听器,然后赋值到成员变量上。weakThreadLocals的赋值是调用方法:

private boolean useWeakThreadLocals()
{
  try {
     if (System.getProperty("com.zaxxer.hikari.useWeakReferences") != null) {   // undocumented manual override of WeakReference behavior
        return Boolean.getBoolean("com.zaxxer.hikari.useWeakReferences");
     }

     return getClass().getClassLoader() != ClassLoader.getSystemClassLoader();
  }
  catch (SecurityException se) {
     return true;
  }
}

这个方法中可以看到首先是使用者配置的时候时候配置了这个选项,如果没有配置,那么检查当前类的类加载器是不是自己定义的类加载器,如果是自己定义的,那么就是弱引用

然后是handoffQueue、waiters和sharedList的实例化。最后的threadList实例化的时候需要检查是否是弱引用,如果是弱引用,那么实例化的是一个16容量的ArrayList,如果不是,那么用的是作者自己开发的FastList。

方法

  • public T borrow(long timeout, final TimeUnit timeUnit) throws InterruptedException
public T borrow(long timeout, final TimeUnit timeUnit) throws InterruptedException
{
  // Try the thread-local list first
  final List<Object> list = threadList.get();
  for (int i = list.size() - 1; i >= 0; i--) {
     final Object entry = list.remove(i);
     @SuppressWarnings("unchecked")
     final T bagEntry = weakThreadLocals ? ((WeakReference<T>) entry).get() : (T) entry;
     if (bagEntry != null && bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) {
        return bagEntry;
     }
  }

  // Otherwise, scan the shared list ... then poll the handoff queue
  final int waiting = waiters.incrementAndGet();
  try {
     for (T bagEntry : sharedList) {
        if (bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) {
           // If we may have stolen another waiter's connection, request another bag add.
           if (waiting > 1) {
              listener.addBagItem(waiting - 1);
           }
           return bagEntry;
        }
     }

     listener.addBagItem(waiting);

     timeout = timeUnit.toNanos(timeout);
     do {
        final long start = currentTime();
        final T bagEntry = handoffQueue.poll(timeout, NANOSECONDS);
        if (bagEntry == null || bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) {
           return bagEntry;
        }

        timeout -= elapsedNanos(start);
     } while (timeout > 10_000);

     return null;
  }
  finally {
     waiters.decrementAndGet();
  }
}

方法调用传入的两个参数,一个是等待时间的长度,一个是等待时间的单位,如果想要“借”的时间超时,就直接返回null。首先在threadlocal的list从后往前遍历,通过list.remove()方法取出连接后,检查是不是弱引用,如果是弱引用就强转成弱引用。然后检查这个连接是不是空,或者状态是不是未使用状态,如果是的,将该连接的状态改成正在使用,并且返回连接。

如果在threadlocal的list中没有找到,那么先把等待者的计数器+1,然后sharedList进行遍历查找连接,如果里面有未使用的连接,那么将这个连接状态改成正在使用,然后将等待者的计数器-1。

如果还是得不到连接,那么开始循环,直到时间小于10秒钟。循环中一直从handoffQueue中获取连接。

  • public void requite(final T bagEntry)
public void requite(final T bagEntry)
{
  bagEntry.setState(STATE_NOT_IN_USE);

  for (int i = 0; waiters.get() > 0; i++) {
     if (bagEntry.getState() != STATE_NOT_IN_USE || handoffQueue.offer(bagEntry)) {
        return;
     }
     else if ((i & 0xff) == 0xff) {
        parkNanos(MICROSECONDS.toNanos(10));
     }
     else {
        yield();
     }
  }

  final List<Object> threadLocalList = threadList.get();
  if (threadLocalList.size() < 50) {
     threadLocalList.add(weakThreadLocals ? new WeakReference<>(bagEntry) : bagEntry);
  }
}

归还连接,传入参数的就是连接。首先将连接的状态改成未使用,然后遍历等待者,如果存在需要使用连接的等待者,那么直接放到handoffQueue中给借用者使用。如果没有,将该线程阻塞10ms。最后是如果当前线程的连接数少于50条,那么将这个线程加入到该线程的threadlocal中

  • public void add(final T bagEntry)
public void add(final T bagEntry)
{
  if (closed) {
     LOGGER.info("ConcurrentBag has been closed, ignoring add()");
     throw new IllegalStateException("ConcurrentBag has been closed, ignoring add()");
  }

  sharedList.add(bagEntry);

  // spin until a thread takes it or none are waiting
  while (waiters.get() > 0 && bagEntry.getState() == STATE_NOT_IN_USE && !handoffQueue.offer(bagEntry)) {
     yield();
  }
}

添加连接方法,首先要检查是不是已经关闭了,如果被关闭了就不能添加。如果没有关闭,可以在sharedList中增加此连接。如果有消费者在等待并且该连接的状态是未使用并且handoffQueue中不能添加这个连接,那么这个添加线程先休息。

  • public boolean remove(final T bagEntry)
public boolean remove(final T bagEntry)
{
  if (!bagEntry.compareAndSet(STATE_IN_USE, STATE_REMOVED) && !bagEntry.compareAndSet(STATE_RESERVED, STATE_REMOVED) && !closed) {
     LOGGER.warn("Attempt to remove an object from the bag that was not borrowed or reserved: {}", bagEntry);
     return false;
  }

  final boolean removed = sharedList.remove(bagEntry);
  if (!removed && !closed) {
     LOGGER.warn("Attempt to remove an object from the bag that does not exist: {}", bagEntry);
  }

  return removed;
}

移除连接方法,如果这个连接的状态不能从正在使用状态改成移除状态,并且不能从保留状态改成移除状态,并且没有关闭,那么移除失败。然后尝试从sharedList移除这个连接,最后返回list.remove()方法的结果

  • public void close()
@Override
public void close()
{
  closed = true;
}

关闭方法就是将closed的值改成true

  • public List values(final int state)
public List<T> values(final int state)
{
  final List<T> list = sharedList.stream().filter(e -> e.getState() == state).collect(Collectors.toList());
  Collections.reverse(list);
  return list;
}

找出sharedList中指定状态的所有连接。

  • public List values()
public List<T> values()
{
  return (List<T>) sharedList.clone();
}

没有指定状态,那么将sharedList的复制返回

  • public boolean reserve(final T bagEntry)
public boolean reserve(final T bagEntry)
{
  return bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_RESERVED);
}

这个方法是将连接的状态从未使用改成保留,这样就不会被借出去。这个方法主要用于使用values(int)方法,保留的连接可以被删除。

  • public void unreserve(final T bagEntry)
public void unreserve(final T bagEntry)
{
  if (bagEntry.compareAndSet(STATE_RESERVED, STATE_NOT_IN_USE)) {
     // spin until a thread takes it or none are waiting
     while (waiters.get() > 0 && !handoffQueue.offer(bagEntry)) {
        yield();
     }
  }
  else {
     LOGGER.warn("Attempt to relinquish an object to the bag that was not reserved: {}", bagEntry);
  }
}

将连接的状态从保留改成未使用,这样就变得可用,可以让别的线程“借用”

  • public int getWaitingThreadCount()
public int getWaitingThreadCount()
{
  return waiters.get();
}

获取从等待到借用到连接的花费时间

  • public int getCount(final int state)
public int getCount(final int state)
{
  int count = 0;
  for (IConcurrentBagEntry e : sharedList) {
     if (e.getState() == state) {
        count++;
     }
  }
  return count;
}

统计这次调用时指定状态的连接数

  • public int[] getStateCounts()
public int[] getStateCounts()
{
  final int[] states = new int[6];
  for (IConcurrentBagEntry e : sharedList) {
     ++states[e.getState()];
  }
  states[4] = sharedList.size();
  states[5] = waiters.get();

  return states;
}

不明所以的方法,没有使用的方法,不知道为什么没有删除

  • public int size()
public int size()
{
  return sharedList.size();
}

获取共享连接数

  • public void dumpState()
public void dumpState()
{
  sharedList.forEach(entry -> LOGGER.info(entry.toString()));
}

输出共享连接集合中的所有连接到日志

【追光者系列】HikariCP源码分析之ConcurrentBag&J.U.C SynchronousQueue、CopyOnWriteArrayList 所以这就是选择CopyOnWriteArrayList这个并发组件的原因,CopyOnWriteArrayList如何做到线程安全的呢?CopyOnWriteArrayList使用了一种叫。 阅读详情

相关推荐

九、HikariCP 源码分析之 ConcurrentBag 二

list 里的连接,肯定是最后一个是最后放进去的,也就是最近使用过的,这个连接还可以继续使用的可能极大,时间越早的连接,就越可能被其他线程借用走了,所以这就是为什么要倒序遍历,我们要先检查能使用的可能性最大的连接。在从 list 中获取连接的时候,使用的是remove方法,也就是说,无论如何,这个连接的引用我们不在本地保存了,如果它可以用,那么用完之后它又会加入到本地的threadList,如果不能使用了,那么我们就删除了这个无用的连接引用。上面的代码是不完整的,少了一个 do,在最外层,不影响我们分析。

wr_java的博客 458

mysql hikari连接池异常处理(com.zaxxer.hikari.pool.ProxyConnection)

### Cause: com.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully received from the server was 603,312 milliseconds ago. The last packet sent successfully to the server was 603,312 milliseconds ago. is longer than the server con

m0_55476995的博客 3170

源码详解系列(八)--全面讲解HikariCP的使用和源码

本文将包含以下内容(因为篇幅较长,可根据需要选择阅读): 1. 如何使用 HikariCP(入门、JMX 等) 2. 配置参数详解 3. 源码分析

子月生的博客 1807

HikariCP源码之ConcurrentBag

hikariCP源码之ConcurrentBag

何忆清风 402

C#并发集合实战:深入剖析ConcurrentBag与ConcurrentQueue的特性和应用场景

是一个线程安全的无序集合,允许多个生产者线程同时向其中添加元素,多个消费者线程同时从中取出元素。通过使用这些并发集合类,开发者可以在编写多线程程序时避免手动管理锁,简化代码并提高程序的并发性能与稳定性。等,它们专为多线程环境设计,提供线程安全的操作。以下将详细探讨这两个并发集合类的特性和使用方法,并通过代码示例与注释进行演示。是一个线程安全的先进先出(FIFO)队列,允许多线程并发地进行入队(Enqueue)和出队(TryDequeue)操作。在多线程编程中,传统的非线程安全集合类(如。

java专栏 2900

论文学习| PoseDiffusion: 通过扩散辅助的束调整解决姿态估计问题

解决的问题:相机姿态估计,这是计算机视觉中的一个经典问题。提出的方法:一种新的方法,PoseDiffusion,它将Structure from Motion(SfM,从运动中构建结构)问题整合到概率扩散框架中。优势模拟捆绑调整的迭代过程。整合来自极线几何的几何约束。在具有挑战性的场景中(如视角稀疏、基线宽的情况)表现良好。能够为多张图片预测内外参。结果:在现实世界数据集上,PoseDiffusion超越了经典的SfM管道和学习型方法,在不同数据集上具有跨数据集的泛化能力,无需进一步训练。

麻辣小香郭的博客 1990

【追光者系列】HikariCP源码分析之ConcurrentBag&J.U.C SynchronousQueue、CopyOnWriteArrayList...

摘要: 原创出处 微信公众号「工匠小猪猪的技术世界」欢迎转载,保留摘要,谢谢! 1.这是一个系列,有兴趣的朋友可以持续关注 2.如果你有HikariCP使用上的问题,可以给我留言,我们一起沟通讨论 3.希望大家可以提供我一些案例,我也希望可以支持你们做一些调优

weixin_33739627的博客 416

原形网络(Prototypical Networks)基于PyTorch的实现

我在Jay2coomzz的基础上修改了数据处理方式和evaluation_model()方法,作为初学者若有不当之处恳请大家批评指正,原文链接如下: https://blog.csdn.net/weixin_38471579/article/details/102631018 数据集和源码链接将放到评论区 文章目录1 数据集一个简单的数据集介绍数据集处理2 搭建网络CNNProtonets 1 数据集 一个简单的数据集介绍 Omniglot数据集一共包含1623 类手写体,每一类中包含20 个样本。其中.

weixin_43872532的博客 6636

HikariCP 源码分析之 ConcurrentBag 万字详解

HikariCP的ConcurrentBag通过无锁设计和线程本地存储实现了高性能数据库连接池管理。其核心架构包含共享列表(CopyOnWriteArrayList)、线程本地缓存(ThreadLocal)和交接队列(SynchronousQueue),采用CAS操作进行状态转换,优先从本地缓存获取连接,减少全局竞争。相比传统并发容器,ConcurrentBag在高并发场景下性能提升166%,内存分配减少66%,CPU使用降低21%,特别适合读多写少的资源池场景。关键优化包括缓存友好设计、避免伪共享、智能退

油墨香^-^的博客 1092

BUPT软件安全实验三

可以看出栈溢出对程序运行的安全性有很大的威胁,如果不对栈进行保护,只要系统中存在栈溢出漏洞,即可令攻击者通过非正当方法获取操作权限。(6)解决思考题,即:在不修改StackOverrun程序源代码的情况下,构造shellcode,通过JMP ESP的方式实现通过记事本打开shellcode.txt(可使用CreateProcessA或WinExec等API)。查看缓冲区信息,可以看到dest指向地址0x0012FAF0,其为数组的存放起始位置,也就是shellcode注入的起始位置。

7xun's space 1965

国产平替NeuroSky?实测金牛座TGAM脑电模块,从Arduino到Python的完整数据采集指南

本文详细介绍了国产金牛座TGAM脑电模块的完整使用流程,包括硬件连接、数据采集和Python分析。通过Arduino和Python的实战案例,展示了如何从脑电波传感器获取并解析专注度、放松度等数据,适用于专注力训练和脑机接口开发。

weixin_30735745的博客 575

concurrentbag 删除指定元素_HikariCP源码阅读(二)ConcurrentBag与FastList

前言本章学习HikariCP的两个容器类ConcurrentBag和FastList。看看ConcurrentBag与传统阻塞队列相比的优势,比较FastList和JDK的ArrayList的异同,想一想为什么HikariCP需要用这两个特制的容器类。一、IConcurrentBagEntryIConcurrentBagEntry是ConcurrentBag容器里存放的元素。它有四个状态...

weixin_39664136的博客 916

利用CANoe和CAPL实现高效CAN网关设计与仿真

本文详细介绍了如何利用CANoe和CAPL进行高效CAN网关的设计与仿真。通过搭建仿真工程、导入DBC数据库、编写CAPL脚本等步骤,手把手指导读者构建一个连接不同CAN网络的网关模型,实现报文的监听、转发与信号处理,从而在硬件开发前验证逻辑,提升汽车电子开发效率与可靠性。

weixin_29164091的博客 294

Hikaricp源码解读(3)——ConcurrentBag介绍

3、ConcurrentBag介绍 本文以v2.7.2源码为主进行分析 HikariCP连接池是基于自主实现的ConcurrentBag完成的数据连接的多线程共享交互,是HikariCP连接管理快速的其中一个关键点。ConcurrentBag是一个专门的并发包裹,在连接池(多线程数据交互)的实现上具有比LinkedBlockingQueue和LinkedTransferQueue更优越的性能。

taisenki的博客 2057

SAP 物料的与压缩库存数据不一致

总结:发生这个问题的原因多数会发生在测试系统在拷贝正式系统的时候会发生这样的情况,系统在拷贝的时候,业务数据还在发生,就会导致数据拷贝的时候丢失数据。经过查询发现是由于物料分类账中的物料的库存数量和 ACDOCA_M_EXTRACT表中的数量对不上,导致系统抛出报错的信息。由于是测试系统,直接更改表的数据,把ACDOCA_M_EXTRACT表中的库存数据和金额与物料分类账中的数据保持一致。在测试系统中进行501和561增加库存的时候,系统提示物料的预压缩库存数据不一致的报错。

我小时候很黑的博客 3302

【ESP32设备通信】-LoRaWAN网关

在物联网 (IoT) 时代,连接设备和收集数据变得比以往任何时候都更加容易和重要。 LoRaWAN(远程广域网)技术已成为远程、低功耗物联网通信的强大解决方案。 在本教程中,我们将使用 ESp32 构建 LoRaWAN 网关电路,并使用 ESP32 和 BME280 传感器构建传感器节点电路。 对于这两个电路,我们将使用基于 SX1278 (Ra-02) LoRa 模块在设备之间进行无线通信。 我们还将向您展示如何将传感器数据传输到流行的物联网平台 ThingSpeak。

视觉与物联智能 1582

HikariCP 源码看傻了:原来连接池也有 KPI

在Java的世界里,数据库连接池可谓是“兵家必争之地”。从DBCP、C3P0到Druid,再到如今的HikariCP,连接池的演进史,简直就是一部“内卷”的血泪史。大家都在拼命优化,只为那“快那么一点点”的性能提升。而HikariCP,就像是连接池界的“天选之子”,一出道就以“快”闻名天下,甚至被Spring Boot 2.0钦定为默认连接池,这牌面,谁与争锋?那么,HikariCP到底凭什么能“卷”赢其他连接池,坐上“性能之王”的宝座呢?难道它吃了“大力丸”?还是自带“外挂”?

PragueJoker的博客 891

MIKE21 MIKE软件 教程 0.1 软件介绍与教学目录

MIKE 21是一个专业的工程软件包,用于模拟河流、湖泊、河口、海湾、海岸及海洋的水流、波浪、泥沙及环境问题。在MIKE Zero集成平台中,主要有MIKE11,MIKE21,MIKE3三类软件,分别对应一维,二维,三维的水动力模型模拟。同时还包括MIKE HYDRO,MIKE FLOOD等其他功能,各软件的具体介绍请参考DHI公司的官方文档,在此不作赘述。学习过程中,对于任何操作界面的疑问,建议大家仔细阅读帮助文档(在有疑问的界面按F1调出),同时官方也提供了对应的线上和线下教学服务(免费+收费)。

Hello Word 2万+

基于HiKariCP组件,分析连接池原理

HiKariCP作为SpringBoot2框架的默认连接池,号称是跑的最快的连接池,数据库连接池与之前两篇提到的线程池和对象池,从设计的原理上都是基于池化思想,只是在实现方式上有各自的特点;

【积累】,是一个长期持续的过程。 2907

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

hikaricp和mysql驱动_【数据库连接池】HIkariCP的简单学习

今天简单的了解了一下HikariCP的原理,记录了一下在HikariCP的github地址中学习到的东西。只是一个简单的了解,并没有深入的研究。之所以去了解HikariCP是因为SpringBoot默认使用的是HikariCP数据库连接池,想简单的了解一下为什么SpringBoot会使用它,而不是其他的数据库连接池。HikariCP数据源简述HikariCP来自日文,是光的意思。听名字就可以知道它...

weixin_31002379的博客 625

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

HikariCP高性能架构深度解析:从源码剖析三大核心优化策略

HikariCP作为当今Java生态中性能最卓越的数据库连接池,其在JMH基准测试中的表现远超同类产品,成为Spring Boot 2.x的默认连接池选择。但是,卓越的性能背后隐藏着哪些精妙的架构设计?本文将深入HikariCP源码,剖析其三大核心性能优化策略,揭示"快"的本质。核心技术栈零开销设计:FastList数据结构优化字节码工程:Javassist编译时代理生成无锁并发:ConcurrentBag lock-free算法如何在高频操作中消除每一个CPU周期的浪费。

ma451152002的专栏 1258

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

HikariCP 底层

HikariCP为什么这么快? #代码量非常小 要知道对于连接池来讲,代码越少,占用cpu和内存越少,Bug出现几率也是越小,那么代表他的执行率高,这就是为什么HikariCP受欢迎的原因之一 #稳定性,可靠性强 HikariCP是经受了市场的考验,走过太上老君的丹炉,现如今拿到SpringBoot的入场证, 走上了人生巅峰. #速度奇快 光有健壮性可不行,坦克很健壮,却跑不...

ScorpC的博客 339

HikariCP 源码分析:Evict、时钟回拨与连接创建生命周期

本文深入剖析了HikariCP数据库连接池的核心机制。其高性能源于三方面设计:1)智能连接驱逐机制,通过HouseKeeper线程定期扫描,结合无锁设计的ConcurrentBag和异步EvictTask实现高效清理;2)稳健的时钟回拨处理策略,采取"检测即放弃"的保守方式保障可用性;3)清晰的连接生命周期管理,通过PoolEntry的状态流转(创建、借用、归还、驱逐、关闭)形成严谨闭环。这些机制共同确保了HikariCP在资源管理和性能优化上的卓越表现,体现了优秀的工程权衡思想。

油墨香^-^的博客 1128

hikaricp druid比较_HikariCP 了解一下

作者 | 黄永灿后端开发攻城狮,关注服务端技术与性能优化。前言在我们的工作中,免不了要和数据库打交道,而要想和数据库打好交道,选择一款合适的数据库连接池就至关重要,目前业界广为人知的数据库连接池有 Tomcat JDBC Connection Pool、c3p0、DBCP、BoneCP、Druid 等,而我们这次要介绍的主角是 HiKariCP,HiKariCP 号称业界跑得最快的数据库...

weixin_39701834的博客 340

SpringBoot 默认数据库连接池 HikariCP

SpringBoot 默认数据库连接池 HikariCP,介绍、配置、性能测试

lly576403061的博客 7600

HikariCP流程,一图概括了解(源码入门)

【思考】 1、连接池作用:估计都知道,保存数据库连接,避免下次请求时再新建耗时。 2、连接池存什么? 平常可能不太注意,仔细翻翻源码稍微思考一下就知道了。Mysql连接是mysql-connector-java.jar提供的,他给我返回Connection实例。所以连接池存的就是Connection实例,高效的提供给多线程使用。 3、那到底跟我们自己List存一下有什么区别呢?也就是连接池解决什么问题、如何高效:多线程时,每个线程使用一个Connection,可能有100个线程同时getConnectio

haerxiong的专栏 564
上一篇: 【HikariCP】【HikariDataSource】源码学习
下一篇: 【HikariCP】【SuspendResumeLock】源码学习
ColdFireMan
博客等级 码龄10年 27粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值