![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java-多线程
文章平均质量分 68
小猪快跑22
专注于Java以及Android
展开
-
线程池要点分析
一、为什么要线程池?直接使用线程不行吗?线程过多会带来额外的开销,包括线程的创建和销毁。线程的运行需要占用 CPU 的时间片,系统中处于运行状态的线程数量越多,那么每个线程单位时间内分配到的时间片就越少,线程调度带来的上下文切换就会越多,最终导致CPU真正用于计算的时间就会越少。直接使用的线程是无法复用的,而线程池是能够实现线程复用的。二、线程池的好处有哪些?降低资源消耗:线程池能够实现线程复用,那么就可以降低线程的创建和销毁造成的损耗。提高响应速度:当任务到达时,能够被等待任务的线程立即执原创 2022-05-09 10:41:23 · 330 阅读 · 0 评论 -
happens-before中 volatile 原则详解
前言:本篇文章中主要讲解 happens-before 中关于 volatile 原则的理解。volatile 变量规则:对一个volatile域的写,happens-before 于任意后续对这个 volatile 域的读。一、volatile 关键字的作用:可见性:一个线程对共享变量的修改,另一个线程获取到的值一定是修改后的。测试代码如下:public class TestVolatile { static boolean stop = false; public stat原创 2022-01-14 18:00:07 · 799 阅读 · 0 评论 -
ThreadLocal内存泄漏的真正原因
注意:看这篇文章之前得对 ThreadLocal 有个大致的了解,不然看起来还是蛮吃力的。一、内存泄漏是因为弱引用吗?先说结果,内存泄漏的确是因为弱引用引起的,为什么呢?先看下 ThreadLocal 的 set 方法:public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(th原创 2022-01-11 16:13:20 · 426 阅读 · 0 评论 -
深入浅出线:程池的线程回收--回收的是非核心线程吗?
写这篇文章的初衷是在和同事讨论线程池中线程去等待队列里面去取任务是随机的还是有序的,什么意思呢?举个例子,我自定义了下面一个线程池,如下:ExecutorService executorService = ThreadPoolExecutor( 2, 3, 60_000, Ti原创 2022-01-07 19:31:59 · 1693 阅读 · 0 评论 -
Java高频面试:3个线程循环n次,每次分别输出A、B、C
前言:假设有3个线程,循环5次,每次各个线程依次输出A、B、C。如下:thread_1 : >>> Athread_2 : >>> Bthread_3 : >>> Cthread_1 : >>> Athread_2 : >>> Bthread_3 : >>> Cthread_1 : >>> Athread_2 : >>> Bthread_3 :原创 2021-09-30 12:05:56 · 345 阅读 · 0 评论 -
Java 高频面试:2个线程分别依次输出数字和字母
如题:假设有A、B 2个线程,分别依次输出1a2b3c4d,A线程输出数字,B线程输出字母。下面有几种方法,感觉方法1是最容易想到的。方法1:synchronized 和 wait/notify/** * 使用 synchronized 和 wait notify */ private static void func1() { char[] num = new char[]{'1', '2', '3', '4'}; char[] str =原创 2021-09-27 09:15:57 · 393 阅读 · 0 评论 -
ReentrantLock 以及 Condition深度解析
前言之前写过关于AQS的文章,也讲了关于 ReetrantLock 的源码分析。写ReentrantLock那么还是得提下 AQS 的。一、关于AQS 中几个重要的属性AQS 中维护了一个很重要的变量 state, 它是int型的,表示加锁的状态,初始状态值为0;另外 AQS 还维护了一个很重要的变量exclusiveOwnerThread,它表示的是获得锁的线程,也叫独占线程,ReentrantLock中的可重入就是用到该属性,当 state != 0 但是 exclusiveOwnerThre原创 2021-09-02 21:32:31 · 2464 阅读 · 3 评论 -
为什么多生产、消费者要使用notifyAll而不是notify
notify 和 notifyAll 的区别?1.线程调用了wait()方法,便会释放锁,并进入等待池中,不会参与锁的竞争2. 调用notify()后,等待池中的某个线程(只会有一个)会进入该对象的锁池中参与锁的竞争,若竞争成功,获得锁,竞争失败,继续留在锁池中等待下一次锁的竞争。3.调用notifyAll()后,等待池中的所有线程都会进入该对象的锁池中参与锁的竞争。锁池和等待池锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(原创 2021-08-23 21:01:58 · 364 阅读 · 2 评论 -
线程池之如何动态调节线程个数和线程池是如何处理抛出异常的线程
一、线程池是如何动态调节线程个数为什么要动态调节线程的个数呢?比方说我们公司在晚上7点的时候有免费的加班餐,大家可以在App上使用企业支付来免费吃饭,所以会有一个高峰期,这时候就可以把线程池的线程数提高,9点之后再降下来。我之前分析了线程池的 回收、执行等源码,大家可以先去看看:手把手教你线程池源码分析如何调节呢?可以调用线程池的 的 如下方法:// 设置核心线程大小executorService.setCorePoolSize(10);// 设置最大线程大小,为什么要设置这个呢?下面会分原创 2020-12-24 11:05:32 · 901 阅读 · 0 评论 -
深入浅出 线程池 shutDown 和 shunDownNow的区别
前言本文接上篇线程池的源码分析,上篇主要通过实例且围绕源码分析了 线程池的 线程复用、线程回收以及执行原理。由于上篇文章的篇幅太长了,所以才有了本姊妹篇。深入浅出线程池的源码一、shutDown 和 shutDownNow 的区别1. shutDown 方法会把线程池的状态置为 SHUT_DOWN,shutDownNow 将线程池的状态设置为 STOP2. shutDown 不会中断正在运行执行任务的线程,而 shutDownNow 则会调用 interrupt() 方法来中断阻塞的任务。阻塞的任原创 2020-10-28 18:47:10 · 877 阅读 · 0 评论 -
通过实例来透彻分析线程池的源码---ThreadPoolExecutor
讲线程池的原理之前,先得了解一下线程池中几个重要的概念。核心线程数 (corePoolSize):核心线程的数量;它的作用可以这样理解:向线程池中添加任务,如果线程池中的线程数量小于 corePoolSize,那么直接新建线程执行任务;如果线程池中的线程数量大于corePoolSize,那么就会往 阻塞队列workQueue中添加任务,此时如果阻塞队列满了且线程池中的线程数量小于最大线程数 maximumPoolSize,那么也会新建一个线程执行任务;如果阻塞队列满且线程数量大于最大线程数maxim原创 2020-10-27 19:05:08 · 550 阅读 · 0 评论 -
CyclicBarrier的使用和源码解析
CyclicBarrier 的介绍CyclicBarrier 的结构很简单,有一个静态内部类 Generation,这个内部类非常的简单,只有一个属性 broken。 CyclicBarrier 还有2个重要的属性 count 和 parties;parties 表示被阻塞线程的个数;count 计数器,它有2点需要注意:它的初始值等于patiies ,在线程的run方法中调用CyclicBarrier 的 await()方法就count 就会减 1当count的值等于0时,它将再次赋值为 pa原创 2020-09-30 15:44:51 · 204 阅读 · 0 评论 -
CountDownLatch的使用和源码解析
看这篇文章最好有点AQS的基础,可以看我的另外的博客:AQS源码解析一、CountDownLatch 是什么,有什么作用?CountDownLatch 就是一个同步倒数计算器,代码结构很简单,如下图:CountDownLatch类是一个同步倒数计数器,构造时传入int型的参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,计数器大于0 时, await()方法会阻塞后面程序执行,直到计数器为0,后面被阻塞的方法才会得以实行。await(long timeout, Tim原创 2020-09-29 10:22:41 · 160 阅读 · 0 评论 -
Java多线程同步操作中为什么要用 while 而不是 if
比方说在多生产、多消费的场景这里直接举例来说明吧class Buf{ private final int MAX = 5; private final ArrayList<Integer> list = new ArrayList<>(); synchronized void put(int v) throws InterruptedException { if (list.size() == MAX) { wait原创 2020-07-08 16:42:36 · 969 阅读 · 2 评论 -
全网最详细的ReentrantReadWriteLock源码解析
前言:之前的文章讲了AQS 和 ReentrantLock 的实现,想看之前的文章可以点击Java高频面试之— AQS原理解析。ReentrantReadWriteLock 的实现也是基于AQS实现的,代码也不是很复杂,下面开讲。简介之前讲到 AQS 有2个最重要的属性, state, 它是int型的,表示加锁的状态,初始状态值为0;另外 一个是 exclusiveOwnerThread,它表示的是获得锁的线程,也叫独占线程。AQS中还有一个用来存储获取锁失败线程的队列,以及head 和 tail原创 2020-06-22 16:14:27 · 1239 阅读 · 3 评论 -
Java高频面试之--- AQS原理解析
什么是AQS?AQS有什么用呢?本篇文章主要就是解决这两个问题,并且附上源码解析。AQS 的全称是 AbstactQueuedSynchronizer 即抽象队列同步器。可能大部分使用Java语言的同学都知道它,因为他是面试的高频问题之一,面试Android也会问这样的问题,我自己就被问了好几次。java并发包下很多API都是基于AQS来实现的加锁和释放锁等功能的,AQS是java并发包的...原创 2020-04-30 10:36:48 · 6006 阅读 · 6 评论 -
为什么 wait 或者 Condition 的 await 要放在同步块中
我们一般的写法就是 对象的 wait 或者 Condition 的 await 方法都放在 同步块中,为什么要这样呢?可能有人说不这样会报 IllegalMonitorStatesException样式,这个应该是结果而不是原因,面试中这样说肯定是不成的。要说明这个问题,我这里用生产、消费者模型来做说明,用的是 Condition 的 await 和 signal 方法。下面直接来看代码:...原创 2019-12-25 11:12:56 · 443 阅读 · 0 评论 -
Java FutureTask 最易懂的源码解析
前言,最近在复习高并发的一些知识点,看到了FutureTask的时候,我感觉还是稍微有点复杂,于是多看几遍了,然后呈现如下的源码+例子。FutureTask 的突出的功能点FutureTask 可以获得线程的执行结果;FutureTask 可以中断正在执行的线程**他们是怎么实现的呢?**我们带着问题往下分析吧。一、FutureTask 结构1.FutureTask 实现了 R...原创 2019-11-04 18:30:05 · 232 阅读 · 0 评论 -
我对CAS的一些理解和用法
前言:之前也一直看到CAS的一些操作,知道CAS是一种乐观锁,通过比较和替换来更新值。今天在看ConcurrentHashMap的时候,发现里面涉及很多的CAS操作,于是有了本文,代码中都有注释。public class TestCAS { public static void main(String[] args) {// Node node = new Node(4)...原创 2019-10-30 16:39:39 · 950 阅读 · 0 评论 -
Java多线程系列之二 ---- 对象锁的深度理解
前言好久之前写了一篇关于多线程的文章算是系列之一吧,链接如下:透彻理解Java类锁和对象锁这里总结下前面所讲的类锁和对象锁的区别:1.类锁和对象锁类锁和对象锁是两种不同的锁,对静态方法加synchronized关键字或者代码块加synchronized(.class)就是类锁;对非静态方法加synchronized或 代码块加synchronized(object)则是对象锁;2.区别...原创 2019-08-15 18:01:37 · 211 阅读 · 1 评论 -
Java 由volatile 关键字到Double-Check单例模式
首先看下关键字volatile 的作用:1.volatile 保证了可见性,保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。2.volatile 不能保证原子性;什么是原子性呢?原子性: 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行 。例如:i++ 这个操作就不具备原子性:因为它包含3步:读...原创 2019-06-20 15:13:36 · 728 阅读 · 2 评论 -
Java高频面试之多线程:有4个线程分别获取C、D、E、F盘的大小,第5个线程统计总大小
前言:之前看到一个Java的面试题,最近在看《Java多线程编程核心技术》然后就试着去解决这道题,这里给出一个个人认为最简单的方法:主要用到的方法是:CountDownLatch, CountDownLatch类是一个同步倒数计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,计数器大于0 时, await()方法会阻塞后面程序执行,直到计数器原创 2017-03-06 09:57:13 · 8047 阅读 · 4 评论 -
java 多线程之wait、notify详解
wait 和 notify以及notifyAll(1)、方法介绍## 1.wait、notify以及notifyAll都是Object对象的方法,他们必须在被 synchronized 同步的方法或代码块中调用,否则会报错。## 2. 调用wait方法会使该线程进入等待状态,并且会释放被同步对象的锁。## 3. notify操作可以唤醒一个因执行wait而处于阻塞状态的线程,使其进入就绪状态,被唤醒原创 2017-02-21 14:01:13 · 4983 阅读 · 0 评论 -
透彻理解 Java synchronized 对象锁和类锁的区别
synchronized 加到 static 方法前面是给class 加锁,即类锁;而synchronized 加到非静态方法前面是给对象上锁。这两者的区别我用代码来演示下:对象锁和类锁是不同的锁,所以多个线程同时执行这2个不同锁的方法时,是异步的。在Task2 中定义三个方法 doLongTimeTaskA和doLongTimeTaskB是类锁,而doLongTimeTaskC是对象锁。pub原创 2017-02-17 14:34:05 · 25688 阅读 · 9 评论