
Java并发编程
文章平均质量分 90
Java并发编程
程光CS
Auf dem Wasser zu singen, Op.72, D.774 - Auf dem Wasser zu singen, Op.72, D.774
展开
-
Java并发编程(11) —— CountDownLatch原理详解
在日常开发中经常会遇到需要在主线程中开启多个线程去并行执行任务,并且主线程需要等待所有子线程执行完毕后再进行汇总的场景。在 CountDownLatch 出现之前一般都使用线程的join()方法来实现这一点,但是 join 方法不够灵活,不能够满足不同场景的需要,所以JDK开发组提供了 CountDownLatch 这个类,使用CountDownLatch 会更优雅。并且CountDownLatch 可以在子线程的任何位置让 await 方法返回而不一定必须线程结束,这比join更加灵活。原创 2023-07-15 17:26:46 · 669 阅读 · 0 评论 -
Java并发编程(10) —— ReentrantLock类详解
一、ReentrantLock介绍ReentrantLock是juc.locks包中的一个独占式可重入锁,相比synchronized,它可以创建多个条件等待队列,还支持公平/非公平锁、可中断、超时、轮询等特性。ReentrantLock实现Lock接口实现了一个锁所需的方法,如lock()、unLock()等,在这些方法中实际上是调用继承了AQS的同步器Sync对象中的方法来实现对锁资源的获取与释放,而内部类Sync有两个子类FairSync和NonfairSync,分别对应公平锁和非公平锁。Ree原创 2023-07-15 15:05:10 · 926 阅读 · 0 评论 -
Java并发编程 —— ThreadPoolExecutor线程池详解
线程池是一种池化技术,是管理一系列线程的资源池。当有任务要处理时,直接从线程池中获取线程来处理,处理完之后线程并不会立即被销毁,而是等待下一个任务。这样实现线程的复用,避免重复创建与销毁线程的开销和大量线程上下文切换,提高系统效率和并发度。使用线程池的好处:1. **降低资源消耗**。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。2. **提高响应速度**。当任务到达时,任务可以不需要等到线程创建就能立即执行。3. **提高线程的可管理性**。线程是稀缺资源,如果无限制的创建,不仅会消耗系原创 2023-04-26 21:01:51 · 4532 阅读 · 0 评论 -
Java并发编程 —— ThreadLocal详解
ThreadLocal用于提供线程内部共享的变量,每个线程在访问ThreadLocal实例的时候都可以获得自己的、独立初始化的变量副本,这样线程间互不干扰,从而避免了线程安全问题。比如我们知道SimpleDateFormat是线程不安全的,多个线程同时用一个SimpleDateFormat对象解析日期时间会报错,但是在一个线程中每解析一个数据就创建一个SimpleDateFormat对象显然也很浪费,这时候我们就可以通过ThreadLocal.withInitial()方法创建一个ThreadLocal实例原创 2023-04-26 09:22:37 · 900 阅读 · 0 评论 -
Java并发编程 —— 延迟队列DelayQueue源码解析
DelayQueue是一个支持并发的无界延迟队列,队列中的每个元素都有个预定时间,当线程从队列获取元素时,只有到期元素才会出队列,没有到期元素则阻塞等待。队列头元素是最快要到期的元素。因此DelayQueue可用于实现定时任务队列。DelayQueue中的主要成员变量和方法如下:**q**:使用优先队列PriorityQueue存储数据,队列中的元素需实现Delayed接口,实现getDelay()和compareTo()方法,以实现优先队列内部的优先级比较,剩余到期时间越短的元素优先级越高原创 2023-04-21 10:32:10 · 1134 阅读 · 0 评论 -
Java并发编程(8) —— AQS抽象同步队列详解
AbstractQueuedSynchronizer抽象同步队列简称AQS,它是实现锁和同步器的基础组件,并发包中锁的底层就是使用AQS实现的。AQS 为构建锁和同步器提供了一些通用功能的实现,因此使用 AQS 能简单且高效地构造出应用广泛的大量的同步器,比如ReentrantLock,Semaphore,ReentrantReadWriteLock,SynchronousQueue等等皆是基于 AQS 的原创 2023-04-12 21:58:26 · 1898 阅读 · 0 评论 -
Java并发编程(7) —— 锁的分类概述
悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(如共享数据被修改),所以**每次在获取资源操作的时候都会上排它锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。**也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。像Java中synchronized和ReentrantLock 等独占锁就是悲观锁思想的实现。悲观锁通常多用于写多比较多的情况下(**多写场景**),避免频繁失败和重试影响性能。原创 2023-04-08 15:39:45 · 551 阅读 · 0 评论 -
Java并发编程(6) —— 什么是死锁
多个线程互相持有并且不释放对方需要的资源因此都处于无限阻塞的状态,称为死锁。二、产生死锁的四个必要条件1. **互斥条件**:该资源任意一个时刻只由一个线程占用。2. **请求与保持条件**:一个线程因请求资源而阻塞时,对已获得的资源保持不放。3. **不剥夺条件**: 线程已获得的资源在未使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。4. **循环等待条件**: 若干线程之间形成一种头尾相接的循环等待资源关系。## 三、如何避免死锁破坏死锁的产生的必要条件即可:1. 破坏请原创 2023-04-08 08:33:32 · 370 阅读 · 0 评论 -
Java并发编程(5) —— synchronized关键字详解
在上一篇中我们提到了volatile关键字可通过插入内存屏障的方式来保证变量的可见性(每次使用都到主存中进行读取)和有序性(不允许指令重排序),但是volatile关键字不保证对变量复合操作的原子性,例如i++操作在jvm层面实际上是通过多条指令操作完成,而若用synchronized 关键字将操作代码块包起来,则同一时刻只有一个线程能进入进行操作,这就保证了原子性。在 Java 早期版本中,synchronized 属于 重量级锁,效率低下。这是因为监视器锁(monitor)是依赖于底层的操作系统的原创 2023-04-07 20:41:38 · 454 阅读 · 0 评论 -
Java并发编程(4) —— Java 内存模型(JMM)详解
CPU 从单核发展为多核,导致出现了多个核间的缓存一致性问题 --> 为了解决缓存一致性问题,提出了 MESI 协议 --> 完全遵守 MESI 又会给 CPU 带来性能问题 --> CPU 设计者为了提高性能又在cache基础上增加 store buffer 和 invalid queue --> 又导致了缓存的顺序一致性变为了弱缓存一致性 --> 需要缓存的顺序一致性的,就需要软件工程师自己在合适的地方添加内存屏障,volatile 的作用之一就是给虚拟机看让其在对应的指令加入内存屏障。原创 2023-04-05 21:37:12 · 933 阅读 · 0 评论 -
Java并发编程(3) —— 线程的生命周期和状态
## 一、Java线程的六种状态Thread类中的枚举类State展示了Java线程的六种状态,线程在运行的生命周期中的指定时刻只可能处于下面 6 种不同状态的其中一个状态:- NEW: 初始状态,线程被创建出来但没有被调用 start() 。- RUNNABLE: 运行状态,线程被调用了 start()开始运行的状态。- WAITING:等待状态,表示该线程需要等待其他线程做出一些特定动作(通知或中断)才能恢复运行。- TIME_WAITING:超时等待状态,可以在指定的时间后自行返回而不是像原创 2023-03-13 17:14:08 · 886 阅读 · 1 评论 -
Java并发编程(2) —— 线程创建的方式与原理
## 一、Java线程创建的三种方式### 1. 继承Thread类并重写run()方法 ### 2. 使用Runnable配合Thread ### 3. 使用FutureTask配合ThreadFutureTask实现了Runnable接口,故可视作任务,并且任务执行结束后可以返回值。FutureTask能够接收Callable 类型的参数,用来处理有返回结果的情况。## 二、线程创建的原理以上创建线程的方法看起来有三种,实际上内部都是通过调用start()方法去创建并关联一个内核线程然后执行r原创 2023-03-13 17:10:50 · 455 阅读 · 0 评论 -
Java并发编程(1)—— 操作系统、Linux、Java中进程与线程的区别
线程和进程都是操作系统中定义的结构,进程是系统中一个独立的活动程序,比如像QQ、网易云音乐,进程是操作系统进行资源分配的基本单位,一个进程中的所有线程共享进程内的资源,而线程则是进程中真正执行程序的工作单位,一个进程中由于多子任务需要可能有多个线程,每个线程都是系统运行过程中的一个独立的指令执行流,主要是基于多任务并行处理的需要设计实现的,是操作系统进行CPU调度的基本单位,由操作系统根据调度算法对系统内所有线程进行调度轮流占用CPU执行程序,这称为并发执行,基于此我们才能在宏观上看到计算机上多个程序像是在原创 2023-02-26 22:55:27 · 1091 阅读 · 0 评论