53.ReentrantReadWriteLock应用之缓存

[TOC]一、缓存更新策略更新时,是先清缓存还是先更新数据库先清缓存,再更新数据库结果:造成查询的值和数据库中的值不一致先更新数据库,再清除缓存结果:造成A线程首次查询和后续查询得到不一致的结果,首次查询得到 x=1,后续查询发现已经清空了缓存,需要去数据库中查得 x=2补充一种情况,假设查询线程 A 查询数据时恰好缓存数据由于时间到期失效,或是第一次查询这种情况的出现几率非常小,见 facebook 论文总结先清缓存:可能造成刚清理缓存还没有更新数据库,高并发下,其他线程直接查询了数据库过期数据到缓存中,这种情况非常严重,直接导致后续所有的请求缓存和数据库不一致。先更新据库:可能造成刚...

Java 2022-11-27 PM 623℃ 0条

52.ReentrantReadWriteLock介绍

[TOC]前言之前也整理过一篇关于读写锁的文章:《Java锁--读写锁简介》,现在又碰到这个话题,就在系统清晰的整理一遍,温故一下之前所学习的并发知识。一、概述ReentrantLock是独占锁,某一时刻只有一个线程可以获取该锁,而实际上会存在很多读多写少的场景,而读操作本身并不会存在数据竞争问题,如果使用独占锁,可能会导致其中一个读线程使其他的读线程陷入等待,降低性能。针对这种读多写少的场景,读写锁应运而生。读写锁允许同一时刻有多个读线程访问,但在写线程访问时,所有的读线程和其他写线程均被阻塞。JUC包中的读写锁接口为ReadWriteLock:public interface Rea...

Java 2022-11-27 PM 698℃ 0条

51.ReentrantLock原理

[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...

Java 2022-11-26 PM 597℃ 0条

50.AQS实现原理介绍

[TOC]前言Java.util.concurrent(J.U.C)大大提高了并发性能,AQS是JUC的核心,是阻塞式锁相关的同步器工具的框架,是一个主要用来构建锁和同步器的抽象类。一、AQS介绍AQS 全程为 AbstractQueuedSynchronizer,它提供了一个 FIFO 队列,可以看成是一个用来实现同步锁及其它涉及到同步功能的核心组件,常见的有,ReentrantLock、CountDownLatch等AQS是一个抽象类,主要通过继承的方式来使用,它本身没有实现任何的同步接口,仅仅是定义了同步状态的获取以及释放的方法来提高自定义的同步组件。AQS 核心思想如果被请求的共...

Java 2022-11-26 PM 659℃ 0条

49.Fork&Join框架介绍

[TOC]一、概述Fork/Join 是 JDK 1.7 加入的新的线程池实现,它体现的是一种分治思想,适用于能够进行任务拆分的CPU密集型运算。所谓的任务拆分,是将一个大任务拆分为算法上相同的小任务,直至不能拆分可以直接求解。跟递归相关的一些计算,如归并排序、斐波那契数列、都可以用分治思想进行求解。Fork/Join 在分治的基础上加入了多线程,可以把每个任务的分解和合并交给不同的线程来完成,进一步提升了运算效率。Fork/Join 默认会创建与CPU核心数大小相同的线程池。二、Fork/Join框架介绍Fork/Join框架主要包含三个模块:线程池:ForkJoinPool任务对象:...

Java 2022-11-24 PM 696℃ 0条

48.Tomcat线程池简单介绍

[TOC]前言tomcat的线程池扩展了jdk的executor,而且队列用的是自己的task queue,因此其策略与jdk的有所不同。本篇将讨论一下tomcat线程池和jdk线程池的不同之处,以及tomcat为什么要重写jdk线程池的方法。一、Tomcat的请求处理过程一个客户端请求到达Tomcat之后的处理流程如上图所示:当Tomcat启动后,Connector的接收器Acceptor会监听是否有客户端连接。一旦监听到客户端连接,则将连接交给线程池Executor,开始执行请求响应任务。Http11Processor负责从客户端连接中读取Http报文并进行解析,解析后的报文封装成R...

Java 2022-11-23 PM 1028℃ 0条

47.任务调度线程池介绍

[TOC]前言JDK 1.5开始提供ScheduledThreadPoolExecutor类,ScheduledThreadPoolExecutor类继承ThreadPoolExecutor类重用线程池实现了任务的周期性调度功能。在JDK 1.5之前,实现任务的周期性调度主要使用的是Timer类和TimerTask类。本文将简单介绍ScheduledThreadPoolExecutor类与Timer类的区别,ScheduledThreadPoolExecutor类相比于Timer类来说,究竟有哪些优势,以及二者分别实现任务调度的简单示例。一、Timer与TimerTask概述使用 Tim...

Java 2022-11-22 PM 744℃ 0条

46.异步模式之工作线程

[TOC]一、定义让有限的工作线程(Worker Thread)来轮流异步处理无限多的任务。也可以将其归类为分工模式,它的典型实现就是线程池,也体现了经典设计模式中的享元模式。例如,海底捞的服务员(线程),轮流处理每位客人的点餐(任务),如果为每位客人都配一名专属的服务员,那 么成本就太高了(对比另一种多线程设计模式:Thread-Per-Message)注意,不同任务类型应该使用不同的线程池,这样能够避免饥饿,并能提升效率例如,如果一个餐馆的工人既要招呼客人(任务类型A),又要到后厨做菜(任务类型B)显然效率不咋地,分成服务员(线程池A)与厨师(线程池B)更为合理,当然你能想到更细致的...

Java 2022-11-21 PM 522℃ 0条

45.ThreadPoolExecutor线程池提交和关闭方法介绍

[TOC]一、线程池提交任务方法线程的各种提交方式的概念:// 执行任务 void execute(Runnable command); // 提交任务 task,用返回值 Future 获得任务执行结果,会有返回值 <T> Future<T> submit(Callable<T> task); // 提交 tasks 中所有任务 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) thr...

Java 2022-11-20 PM 752℃ 0条

44.Executors创建线程池方法介绍

[TOC]一、Executors类概述Executors是Executor框架的工具类,提供了几种线程池创建方法,以及线程池中默认配置(如线程工厂)的处理,下面会对其中常用的几种创建线程池的方式进行说明。线程池的创建分为两种方式:ThreadPoolExecutor 和 Executors;二、Executors常用的方法方法说明public static ExecutorService newFixedThreadPool(int nThreads)一种线程数量固定的线程池,当线程处于空闲状态时,他们并不会被回收,除非线程池被关闭。当所有的线程都处于活动状态时,新的任务都会处于等待状态...

Java 2022-11-18 PM 588℃ 0条