吃透Java
专注Java技术,每天都要努力一点点
展开
-
吃透Java并发二十二:并发集合之ConcurrentHashMap(2) 扩容
一、扩容的基本思路JDK1.8中,ConcurrentHashMap最复杂的部分就是扩容/数据迁移,涉及多线程的合作和rehash。我们先来考虑下一般情况下,如何对一个Hash表进行扩容。1、扩容思路Hash表的扩容,一般都包含两个步骤:①table数组的扩容table数组的扩容,一般就是新建一个2倍大小的槽数组,这个过程通过由一个单线程完成,且不允许出现并发。②数据迁移所谓数据迁移...原创 2020-02-17 14:51:47 · 493 阅读 · 0 评论 -
吃透Java并发二十一:并发集合之ConcurrentHashMap(1) 原理
一、ConcurrentHashMap类简介ConcurrentHashMap是在JDK1.5时,J.U.C引入的一个同步集合工具类,顾名思义,这是一个线程安全的HashMap。不同版本的ConcurrentHashMap,内部实现机制千差万别,本节所有的讨论基于JDK1.8。ConcurrentHashMap的类继承关系并不复杂:可以看到ConcurrentHashMap继承了Abstr...原创 2020-02-16 21:31:31 · 415 阅读 · 0 评论 -
吃透Java并发二十:线程池之Fork/Join框架(2)实现
一、引言回顾一下,Fork/Join框架的核心实现类是ForkJoinPool线程池,其它核心组件包括:ForkJoinTask(任务)、ForkJoinWorkerThread(工作线程)、WorkQueue(任务队列)。这一章,我们将深入F/J框架的实现细节,看看ForkJoinPool线程池究竟有何特殊之处,F/J框架的整个任务调度流程又是怎样的。二、任务调度流程在开始之前,先来看下...原创 2020-02-13 15:38:27 · 290 阅读 · 0 评论 -
吃透Java并发十九:线程池之Fork/Join框架(1) 原理
一、引言算法领域有一种基本思想叫做“分治”,所谓“分治”就是将一个难以直接解决的大问题,分割成一些规模较小的子问题,以便各个击破,分而治之。比如:对于一个规模为N的问题,若该问题可以容易地解决,则直接解决;否则将其分解为K个规模较小的子问题,这些子问题互相独立且与原问题性质相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解,这种算法设计策略叫做分治法。许多基础算法都运用了“分治”...原创 2020-02-12 21:18:14 · 357 阅读 · 0 评论 -
吃透Java并发十八:线程池之Future
一、Future简介Future主要作用就是异步地执行任务,并在需要的时候获取结果。我们知道,一般调用一个函数,需要等待函数执行完成,调用线程才会继续往下执行,如果是一些计算密集型任务,需要等待的时间可能就会比较长。而Future可以让调用方立即返回,然后它自己会在后面慢慢处理,此时调用者拿到的仅仅是一个凭证,调用者可以先去处理其它任务,在真正需要用到调用结果的场合,再使用凭证去获取调用结果。这...原创 2020-02-08 16:07:09 · 746 阅读 · 0 评论 -
吃透Java并发十七:线程池之ScheduledThreadPoolExecutor
一、ScheduledThreadPoolExecutor简介我们曾经提到过一种可对任务进行延迟/周期性调度的执行器(Executor),这类Executor一般实现了ScheduledExecutorService这个接口。ScheduledExecutorService在普通执行器接口(ExecutorService)的基础上引入了Future模式,使得可以限时或周期性地调度任务。Sche...原创 2020-02-07 13:11:52 · 812 阅读 · 0 评论 -
吃透Java并发十六:线程池之ThreadPoolExecutor
一、ThreadPoolExecutor简介ThreadPoolExecutor,它是J.U.C在JDK1.5时提供的一种实现了ExecutorService接口的执行器,或者说线程池。通过Executors工厂,用户可以创建自己需要的执行器对象。ThreadPoolExecutor并没有自己直接实现ExecutorService接口,因为它只是其中一种Executor的实现而已,所以Doug...原创 2020-02-06 15:28:24 · 416 阅读 · 0 评论 -
吃透Java并发十五:线程池框架
一、概述executors框架是整个J.U.C包中类/接口关系最复杂的框架,真正理解executors框架的前提是理清楚各个模块之间的关系,高屋建瓴,从整体到局部才能透彻理解其中各个模块的功能和背后的设计思路。Executors框架的整体结构如下:二、核心接口1、ExecutorExecutor是JDK1.5时,随着J.U.C引入的一个接口,引入该接口的主要目的是解耦任务本身和任务的执...原创 2020-02-04 18:00:55 · 1015 阅读 · 0 评论 -
吃透Java并发十四:locks之ReentrantReadWriteLock
一、ReentrantReadWriteLock类简介ReentrantReadWriteLock类,顾名思义,是一种读写锁,它实现了ReadWriteLock接口,该类在内部实现了具体独占锁特点的写锁,以及具有共享锁特点的读锁,和ReentrantLock一样,ReentrantReadWriteLock类也是通过定义内部类实现AQS框架的API来实现独占/共享的功能。1、支持公平/非公平策...原创 2020-02-03 19:07:03 · 225 阅读 · 0 评论 -
吃透Java并发十三:locks之ReentrantLock
一、ReentrantLock类简介ReentrantLock类,实现了Lock接口,是一种可重入的独占锁,它具有与使用 synchronized 相同的一些基本行为和语义,但功能更强大。ReentrantLock内部通过内部类实现了AQS框架(AbstractQueuedSynchronizer)的API来实现独占锁的功能。ReentrantLock类的其中一个构造器提供了指定公平策略 / ...原创 2020-02-02 18:36:51 · 322 阅读 · 0 评论 -
吃透Java并发十二:locks之AQS的Conditon功能
一、概述本章将继续以ReentrantLock的调用为例,说明AbstractQueuedSynchronizer提供的Conditon等待功能。J.U.C包提供了Conditon接口,用以对原生的Object.wait()、Object.notify()进行增强。Condition接口的实现类其实是在AQS中——ConditionObject,ReentranLock的newCondito...原创 2020-02-02 17:39:52 · 251 阅读 · 0 评论 -
吃透Java并发十一:locks之AQS共享功能分析
一、概述我们通过ReentrantLock的示例,分析了AQS的独占功能。本节将以CountDownLatch为例,分析AQS的共享功能。CountDownLatch是一个辅助同步器类,用来作计数使用,它的作用有点类似于生活中的倒数计数器,先设定一个计数初始值,当计数降到0时,将会触发一些事件,如火箭的倒数计时。初始计数值在构造CountDownLatch对象时传入,每调用一次 countD...原创 2020-01-31 21:51:10 · 218 阅读 · 0 评论 -
吃透Java并发十:locks之AQS独占锁功能分析
一、独占锁代表ReentrantLockReentrantLock类,实现了Lock接口,是一种可重入的独占锁,它具有与使用 synchronized 相同的一些基本行为和语义,但功能更强大。ReentrantLock内部通过内部类实现了AQS框架(AbstractQueuedSynchronizer)的API来实现独占锁的功能。ReentrantLock中有一个抽象类Sync继承AQS,它的...原创 2020-01-29 21:20:52 · 321 阅读 · 0 评论 -
吃透Java并发九:locks之AbstractQueuedSynchronizer(AQS)
AbstractQueuedSynchronizer抽象类(以下简称AQS)是整个java.util.concurrent包的核心。在JDK1.5时,Doug Lea引入了J.U.C包,该包中的大多数同步器都是基于AQS来构建的。AQS框架提供了一套通用的机制来管理同步状态(synchronization state)、阻塞/唤醒线程、管理等待队列。我们所熟知的ReentrantLock、Cou...原创 2019-12-15 21:47:41 · 572 阅读 · 3 评论 -
吃透Java并发八:locks之 Lock、ReadWriteLock、Condition接口
一、Lock接口在JDK1.5之前,我们加锁只能通过synchronized关键字。在多线程情况下,一段代码被synchronized关键字修饰,那么同一时刻只能被一个线程访问,其它线程都必须等待该线程释放锁之后才有机会获取锁进入代码块。持有synchronized锁的线程释放锁有如下两种情况:1、代码块执行完毕释放锁。2、执行代码块的线程抛出异常释放锁。假如一个线程执行IO操作或者Sl...原创 2019-12-06 10:32:23 · 382 阅读 · 0 评论 -
吃透Java并发七:locks框架
一、juc-locks框架整体分析早期的JDK版本中,仅仅提供了synchronizd、wait、notify等等比较底层的多线程同步工具,开发人员如果需要开发复杂的多线程应用,通常需要基于JDK提供的这些基础工具进行封装,开发自己的工具类。JDK1.5之后,Doug Lea设计了JUC并发包,其中java.util.concurrent.locks包下提供了一系列基础的锁工具,用以对sync...原创 2019-12-03 20:29:21 · 485 阅读 · 2 评论 -
吃透Java并发六:ThreadLocal
一、ThreadLocal简介ThreadLocal 用一种存储变量与线程绑定的方式,在每个线程中用自己的 ThreadLocalMap 安全隔离变量,为解决多线程程序的并发问题提供了一种新的思路。ThreadLocal不是为了解决多线程访问共享变量,而是为每个线程创建一个单独的变量副本,提供了保持对象的方法和避免参数传递的复杂性。它采用采用空间来换取时间的方式,解决多线程中相同变量的访问冲突问...原创 2019-11-30 20:52:43 · 489 阅读 · 2 评论 -
吃透Java并发五:Java线程安全与锁优化
一、何为线程安全当一个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方法进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的。按照线程安全的“安全程度”由强到弱来排序,我们可以将Java语言中各种操作共享数据分为以下5类:不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。1、不可变在Java...原创 2019-11-23 21:51:01 · 373 阅读 · 2 评论 -
吃透Java并发四:Java内存模型
一、Java内存模型Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。此处的变量是指:实例字段、静态字段和数组对象,但是不包括局部变量和方法参数,因为后者是线程私有的,不会被共享,自然不存在竞争的问题。Java内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存。线程的工作内存中保存了被该线程使用到的变量的主...原创 2019-11-19 21:12:36 · 408 阅读 · 2 评论 -
吃透Java并发三:线程的阻塞与唤醒
一、阻塞与唤醒线程的阻塞和唤醒在多线程并发过程中是一个关键点,当线程数量达到很大的数量级时,并发可能带来很多隐蔽的问题。如何正确暂停一个线程,暂停后又如何在一个要求的时间点恢复,这些都需要仔细考虑的细节。Java为我们提供了多种API来对线程进行阻塞和唤醒操作,比如sleep、suspend与resume、wait与notify以及park与unpark等等。二、sleep()方法控制线程阻...原创 2019-11-15 16:53:28 · 843 阅读 · 1 评论 -
吃透Java并发二:Thread线程用法
一、线程线程是一个独立执行的调用序列,同一个进程的线程在同一时刻共享一些系统资源(比如文件句柄等)也能访问同一个进程所创建的对象资源(内存资源)。每个程序都至少拥有一个线程-即作为Java虚拟机(JVM)启动参数运行在主类main方法的线程。在Java虚拟机初始化过程中也可能启动其他的后台线程。这种线程的数目和种类因JVM的实现而异。然而所有用户级线程都是显式被构造并在主线程或者是其他用户线程...原创 2019-11-14 20:59:26 · 388 阅读 · 3 评论 -
吃透Java并发一:并发基础概念
一、并发与并行并发:对于单CPU的计算机来说,在CPU中,同一时间只能干一件事儿的。为了看起来像是“同时干多件事”,分时操作系统把CPU的时间划分成长短基本相同的”时间片”,通过操作系统的管理,把这些时间片依次轮流地分配给各个用户使用。由于计算机的处理速度很快,只要时间片的间隔取得适当,那么一个用户作业从用完分配给它的一个时间片到获得下一个CPU时间片,中间有所”停顿”,但用户察觉不出来,好像整...原创 2019-11-12 21:04:46 · 516 阅读 · 1 评论