[TOC]前言Mybatis配置文件两大类:Mybatis 主配置文件:提供 Mybatis 全局设置的。包含的内容、日志、数据源、mapper 文件位置等信息。Mybatis 的 mapper 文件:用来写SQL语句。一个表/Mapper接口一个 mapper 文件。一、概述MyBatis的核心配置文件配置了MyBatis的一些全局信息,包含数据库连接信息和MyBatis运行时所需的各种特性,以及设置和影响MyBatis行为的一些属性。这些信息通常在一个项目中只会在一个配置文件中编写,并且编写后也不会轻易更改。虽然在实际项目中需要开发人员编写或者修改的配置文件不多,但是熟悉配置文件中各...
[TOC]一、概述CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。这个屏障之所以用循环修饰,是因为在所有的线程释放彼此之后,这个屏障是可以重新使用的(reset()方法重置屏障点),这一点与CountDownLatch不同。特点CyclicBarrier是一种同步机制允许一组线程相互等待,等到所有线程都到达一个屏障点才退出await方法,它没有直接实现AQS而是借助ReentrantLock来实现的同步机...
[TOC]一、概述CountDownLatch(倒计时锁) 能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。它相当于是一个计数器,这个计数器的初始值就是线程的数量,每当一个任务完成后,计数器的值就会减一,当计数器的值为 0 时,表示所有的线程都已经任务了,然后在 CountDownLatch 上等待的线程就可以恢复执行接下来的任务。应用场景典型的应用场景就是当一个服务启动时,同时会加载很多组件和服务,这时候主线程会等待组件和服务的加载。当所有的组件和服务都加载完毕后,主线程和其他线程在一起完成某个任务。二、常用方法方法说明CountDownLatch(int count)c...
[TOC]一、概述Semaphore是向外分发资源的许可证,可以允许一个或多个任务同时访问资源。Semaphore通过构造参数来指定许可证的数量;acquire方法阻塞式获取许可证;release方法释放许可证。可以将其比喻为地铁的安检,每当人流量高峰的时候,安检会先让几个人进去,然后拦住后面的人,待前面几人通过安检门后,会对后面的人用相同的方式放行。特点Semaphore(信号量)是一种计数器,用来保护一个或者多个共享资源的访问。如果线程要访问一个资源就必须先获得信号量。如果信号量内部计数器大于0,信号量减1,然后允许共享这个资源;否则,如果信号量的计数器等于0,信号量将会把线程置入休...
[TOC]前言ReadWriteLock适用于读多写少的场景,允许多个线程同时读取共享变量。但在读多写少的场景中,还有更快的技术方案。在jdk8以后,java提供了一个性能更优越的读写锁并发类StampedLock,该类的设计初衷是作为一个内部工具类,用于辅助开发其它线程安全组件,用得好,该类可以提升系统性能,用不好,容易产生死锁和其它莫名其妙的问题。本文主要和大家一起学习下StampedLock的功能和使用。一、StampedLock概述StampedLock 是读写锁的实现,对比 ReentrantReadWriteLock 主要不同是该锁不允许重入,多了乐观读的功能,使用上会更加复...
[TOC]一、ReentrantReadWriteLock简单流程1.1 独占获取锁简单流程独占获取锁流程独占锁获取(writeLock写锁),首先判断是否有线程获取了锁,是否有线程获取了锁的判断通过读写锁中通过32位int类型state可以获取,其中低16位表示读锁,高16表示写锁。有读锁:直接排队阻塞。有写锁:还需要判断写锁线程是否是自己,如果是自己就是锁重入了,如果不是自己说明已经有其他的线程获取锁正在执行,那么当前线程需要排队阻塞。无锁:直接获取锁,其他抢占的独占锁线程需要排队阻塞,当前线程执行完毕后释放锁通知下一个排队线程获取锁。1.2 共享获取锁简单流程共享锁获取锁流程独占锁...
[TOC]一、缓存更新策略更新时,是先清缓存还是先更新数据库先清缓存,再更新数据库结果:造成查询的值和数据库中的值不一致先更新数据库,再清除缓存结果:造成A线程首次查询和后续查询得到不一致的结果,首次查询得到 x=1,后续查询发现已经清空了缓存,需要去数据库中查得 x=2补充一种情况,假设查询线程 A 查询数据时恰好缓存数据由于时间到期失效,或是第一次查询这种情况的出现几率非常小,见 facebook 论文总结先清缓存:可能造成刚清理缓存还没有更新数据库,高并发下,其他线程直接查询了数据库过期数据到缓存中,这种情况非常严重,直接导致后续所有的请求缓存和数据库不一致。先更新据库:可能造成刚...
[TOC]前言之前也整理过一篇关于读写锁的文章:《Java锁--读写锁简介》,现在又碰到这个话题,就在系统清晰的整理一遍,温故一下之前所学习的并发知识。一、概述ReentrantLock是独占锁,某一时刻只有一个线程可以获取该锁,而实际上会存在很多读多写少的场景,而读操作本身并不会存在数据竞争问题,如果使用独占锁,可能会导致其中一个读线程使其他的读线程陷入等待,降低性能。针对这种读多写少的场景,读写锁应运而生。读写锁允许同一时刻有多个读线程访问,但在写线程访问时,所有的读线程和其他写线程均被阻塞。JUC包中的读写锁接口为ReadWriteLock:public interface Rea...
[TOC]前言ReentrantLock关系类图:ReentrabtLock实现了LOCK接口,里面维护了一个sync同步器,Sync是一个抽象类,有两种实现FairSync和NonfairSync分别对应着公平锁和非公平锁两种实现。一、非公平锁实现原理1.1 示例代码示例import lombok.extern.slf4j.Slf4j; import java.util.concurrent.locks.ReentrantLock; import static com.lilinchao.concurrent.utils.Sleeper.sleep; /** * Created b...
[TOC]前言Java.util.concurrent(J.U.C)大大提高了并发性能,AQS是JUC的核心,是阻塞式锁相关的同步器工具的框架,是一个主要用来构建锁和同步器的抽象类。一、AQS介绍AQS 全程为 AbstractQueuedSynchronizer,它提供了一个 FIFO 队列,可以看成是一个用来实现同步锁及其它涉及到同步功能的核心组件,常见的有,ReentrantLock、CountDownLatch等AQS是一个抽象类,主要通过继承的方式来使用,它本身没有实现任何的同步接口,仅仅是定义了同步状态的获取以及释放的方法来提高自定义的同步组件。AQS 核心思想如果被请求的共...