
JUC
Java并发包学习总结
每天进步一点点呀
工作日常技术学习、积累、总结
-
原创 面试题之并发相关专栏五
一、请谈谈volatile有什么特点,为什么它能保证变量对所有线程的可见性?当一个变量被volatile修饰后,具备两个特性:保证此变量对所有线程的可见性,当一条线程修改了这个变量的值,新值对于其他线程是可以立即得知的,而普通变量做不到这一点。 禁止指令重排序优化,普通变量仅仅能保证在方法执行过程中,得到正确结果,但是不保证程序代码的执行顺序。内存模型定义了8种内存间操作来保证可见性:...2020-04-05 20:08:22152
0
-
原创 面试题之并发相关专栏四
一、Java中的线程池是如何实现的?在Java中,所谓的线程池中的线程,其实是被抽象为了一个静态内部类Worker,基于AQS实现,存放在线程池的HashSet workers成员变量中; 需要执行的任务存放在成员变量workQueue中,workQueue是一个阻塞队列; 线程池的基本思想就是:从workQueue队列中不断取出需要执行的任务,放在Workers中进行执行;二、如何自定...2020-04-05 20:01:24149
0
-
原创 面试题之并发相关专栏三
一、ReentrantLock是如何实现可重入的?ReentrantLock内部自定义了同步器Sync,其实就是加锁的时候通过CAS算法,将线程对象放到一个双向链表中,每次获取锁的时候,看下当前维护的那个线程ID和当前请求的线程ID是否一样,一样就可重入。二、请说说CyclicBarrier和CountDownLatch的异同?CountDownLatch 是不可以重置的,所以无法重...2020-04-05 19:53:10133
0
-
原创 面试题之并发相关专栏二
一、什么是锁消除和锁粗化?锁消除:指虚拟机即时编译器在运行时,对一些代码上要求同步,但被检测到不可能存在共享数据竞争的锁进行消除。 锁粗化:原则上,同步块的作用范围应该尽可能的小,也就是说锁的粒度要尽可能小一点。但是如果一系列的连续操作都对同一个对象反复加锁和解锁,甚至加锁操作在循环体内,频繁地进行互斥同步也会导致不必要的性能损耗,锁粗化就是增大锁的作用范围。二、为什么说Synchroni...2020-04-05 19:44:42127
0
-
原创 面试题之并发相关专栏一
一、Synchronized用过么?其原理是什么?Synchronized是由JVM虚拟机实现的一种实现互斥同步的方式,被Synchronized修饰后的程序块编译后的字节码文件中,在编译前后被编译器生成了monitorenter和monitorexit两个字节码指令。在虚拟机执行到monitorenter指令时,首先要尝试获取对象的锁,如果这个对象没有锁定,或者当前线程已经拥有了这个对象...2020-04-05 19:31:03167
0
-
原创 JUC学习之AQS抽象队列同步器
一、简介AQS是AbstractQueuedSynchronizer的简写,翻译过来就是:抽象队列同步器。AbstractQueuedSynchronizer在java.util.concurrent.locks包中,声明如下:public abstract class AbstractQueuedSynchronizerextends AbstractOwnableSynchroni...2020-03-14 08:28:25149
0
-
原创 JUC学习之ForkJoinPool分支合并
一、简介JDK7引入了一种新的并发框架 - Fork/Join Framework分支合并框架,同时引入了一种新的线程池ForkJoinPool@sun.misc.Contendedpublic class ForkJoinPool extends AbstractExecutorService { }ForkJoinPool 是ExecutorService的补充,在某...2020-03-13 20:15:50164
0
-
原创 JUC学习之线程池工作原理
一、简介上一篇文章介绍了各种线程池的使用、优势等,本篇我们将去了解线程池底层一点的相关知识。二、线程池底层原理Executor为我们提供了功能各异的线程池,其实其内部很多都是由ThreadPoolExecutor实现的,我们详细了解下ThreadPoolExecutor实现原理不但对我们使用理解Executor提供的线程池大有帮助,也让我们能根据实际情况自定义特定的线程池。我们先...2020-03-12 19:31:15174
0
-
原创 JUC学习之线程池
一、简介首先,我们先了解一下为什么要用线程池?很多年以前,单核CPU的时候,多线程其实是假的,只是线程之间高速切换造成的“多线程”假象。现如今,基本上都是多核CPU电脑,多个线程各自跑在独立的CPU上,不用切换,效率比较高。线程池的主要特点:线程可复用; 控制最大并发数; 管理线程;线程池的优势:线程池主要是控制运行的线程数量,处理过程中将任务加入队列,然后在线程创建后启...2020-03-11 19:46:15134
0
-
原创 JUC学习之ConcurrentHashMap扩容机制
一、简介在ConcurrentHashMap中,比较复杂部分就是其扩容机制,因为涉及到多个线程分工合作完成数据迁移和key的rehash操作。二、扩容思路ConcurrentHashMap扩容一般分为两个步骤:【a】Node<K,V>[] table数组的扩容,一般是扩大到原来数组大小的两倍; 【b】key的rehash以及数据的迁移:因为计算key在桶中的索引ind...2020-03-09 21:15:32245
0
-
原创 JUC学习之ConcurrentHashMap(JDK1.8)
一、简介ConcurrentHashMap是线程安全的HashMap,声明如下:public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V>, SerializableConcurrentHashMap相关类图如下:...2020-03-09 21:06:4896
0
-
原创 JUC学习之CopyOnWriteArraySet
一、简介CopyOnWriteArraySet是线程安全的无序集合,可以将它理解成线程安全的HashSet。CopyOnWriteArraySet和HashSet都继承于共同的父类AbstractSet;但是,HashSet是通过“散列表(HashMap)”实现的,而CopyOnWriteArraySet则是通过上一节刚介绍的CopyOnWriteArrayList写时复制ArrayList实...2020-03-06 22:06:26108
0
-
原创 JUC学习之CopyOnWriteArrayList
一、简介CopyOnWriteArrayList是JDK1.5时J.U.C引入了一个新的集合工具类,方便在并发环境下使用“列表”.public class CopyOnWriteArrayList<E>extends Objectimplements List<E>, RandomAccess, Cloneable, SerializableCopyO...2020-03-06 22:01:43110
0
-
原创 JUC学习之DelayQueue延时队列
一、简介DelayQueue是JUC提供的一种无界延迟队列,它实现了BlockingQueue<E>阻塞队列接口,底层基于已有的PriorityBlockingQueue实现,类声明如下:public class DelayQueue<E extends Delayed>extends AbstractQueue<E>implements Bloc...2020-03-05 22:21:20256
3
-
原创 JUC学习之ArrayBlockingQueue
一、简介ArrayBlockingQueue是一个有界阻塞队列,底层基于数组来实现的。这个队列对元素FIFO(先进先出)排序。队列的头是队列中存在时间最长的元素。队列的尾部是队列中时间最短的元素。新元素插入到队列的尾部,队列检索操作获取队列头部的元素。这是一个典型的“有界缓冲区”,其中大小固定的数组保存由生产者插入并由消费者提取的元素。一旦创建,容量就不能更改。试图将一个元素放入一个满...2020-03-04 21:13:23115
0
-
原创 JUC学习之BlockingQueue和LinkedBlockingQueue
一、简介BlockingQueue,指的是阻塞队列,所谓队列,就是先进先出的一种数据结构。在Java中,BlockingQueue是一个接口,并且继承与Queue<E>接口,类图大体如下:目前已知的实现类有:ArrayBlockingQueue,DelayQueue,LinkedBlockingDeque,LinkedBlockingQueue,LinkedTr...2020-03-03 20:55:4996
0
-
原创 JUC学习之原子变量
一、简介在多线程环境下,如果多个线程需要对共享资源同时进行操作的话,很容易出现数据不一致的情况。通常情况下我们会使用synchronized同步方式来保证线程安全。从JDK 1.5开始提供了java.util.concurrent.atomic包,这个包中的原子操作类提供了一种用法简单、性能高效、线程安全地更新一个变量的方式。在java.util.concurrent.atomic包下...2020-03-02 20:14:23108
0
-
原创 JUC学习之Condition和顺序访问
一、简介JUC提供了Lock可以方便的进行锁操作,但是有时候我们也需要对线程进行条件性的阻塞和唤醒,这时我们就需要Condition条件变量,可以方便的对持有锁的线程进行阻塞和唤醒。Condition将对象监视器方法(wait、notify和notifyAll)分解到不同的对象中,通过将它们与任意锁实现结合使用,实现每个对象具有多个等待集的效果。锁代替同步方法和语句的使用,Conditio...2020-03-01 14:31:26169
0
-
原创 JUC学习之生产者消费者案例(Condition方式)
一、简介上一篇我们介绍了使用传统的synchronized结合wait()/notifyAll()线程通信机制实现了生产者消费者案例,并且介绍了多线程交互中常见的虚假唤醒现象。我们都知道,Lock同步锁其实可以代替synchronized完成同步功能,并且使用起来还没有那么复杂,本文将介绍如何使用Lock实现生产者消费者案例。下表是synchronized和Lock实现线程通信方法的区别:...2020-03-01 14:28:11585
0
-
原创 JUC学习之生产者消费者案例(synchronized方式)
一、简介生产者消费者问题是线程模型中的经典问题,生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。本文我们将总结通过wait()和notify()多线程通信来实现生产者-消费者模式。wait():阻塞线程,将线程加入到等待队列中,会释放锁; notify()/notifyAll():唤醒一个或者多个等待队列中的线程,不会释放锁;二、实现示例...2020-03-01 14:23:5384
0
-
原创 JUC学习之Lock同步锁
一、简介引出Lock同步锁之前,先了解一下synchronized同步的一些缺陷:如果一段代码被synchronized锁住,那么当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁。如果某个时刻获得锁的线程发生阻塞现象,那么这把锁会被它一直持有,而其他线程永远无法获取锁,正常来说,不能让其他线程永远在那里等待。使用Lock锁的话,提供了一种机制可...2020-02-29 10:25:19185
0
-
原创 JUC学习之循环栅栏CyclicBarrier
一、简介前面已经简单介绍了CountDownLatch闭锁,本文的CyclicBarrier其实跟闭锁差不多,当然还是存在一些区别。官网介绍如下:CyclicBarrier是一种同步辅助工具,允许一组线程彼此等待到达一个共同的障碍点。CyclicBarrier在包含固定大小的线程的程序中非常有用,这些线程有时必须彼此等待。这个屏障被称为循环屏障,因为它可以在等待的线程被释放后重新使用。...2020-02-29 09:00:13283
0
-
原创 JUC学习之volatile可见性
一、简介volatile,是Java中的一个关键字。被volatile修饰的变量,在多个线程中保持可见性,注意,volatile不保证原子性,这也是volatile与synchronized的区别之一。那么什么是可见性呢?可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。要了解volatile的工作原理,首先需要了解一下Java内存模...2020-02-27 19:51:12117
0
-
原创 JUC学习之Callable
一、简介Callable接口,其实跟Runnable接口的使用差不多,只不过Callable接口可以有返回值,返回结果并可能引发异常的任务。但是,Runnable不返回结果,也不能抛出checked异常。二、源码@FunctionalInterfacepublic interface Callable<V> { /** * Computes a res...2020-02-26 20:11:50130
0
-
原创 JUC学习之线程8锁
一、简介所谓线程八锁,其实就是就是线程锁的8种情况,对应于是否加上synchronized,是否加上static等8种常见情况,具体见下面详解。二、线程8锁第一种情况: 两个线程调用同一个对象的两个普通同步方法,先打印one还是two?/** * 线程八锁第一种情况: 两个线程调用同一个对象的两个普通同步方法,先打印one还是two? * <p> * 运行结果: ...2020-02-26 20:03:20259
3