![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java高并发
文章平均质量分 87
George&Rita
星光不负赶路人!
展开
-
生产者和消费者问题
生产者-消费者是一个经典的多线程协作问题。所谓生产者-消费者问题,实际上是包含两类线程,一种是生产者线程,用于生产数据,另一种是消费者线程,用于消费数据。为了解耦生产者和消费者的关系,通常会采用共享的数据区域。生产者往共享区域放数据,无需关心消费者的行为。消费者从共享区域取数据,无需关心生产者的行为。接下来,我们介绍几种方法来完成生产者-消费者模型。原创 2022-12-13 20:54:48 · 2414 阅读 · 0 评论 -
深入理解ReentrantReadWriteLock源码
之前我们介绍过ReentrantLock,它是基于AQS同步框架实现的,是一种可重入的独占锁。但是这种锁在读多写少的场景下,效率并不高。因为当多个线程在进行读操作的时候,实际上并不会影响数据的正确性。因此针对读多写少的场景,java提供了ReentrantReadWriteLock(可重入读写锁)。读写锁允许同一时刻被多个读线程访问,但是当写线程在访问时,其他所有的读线程和写线程都会被阻塞。ReentrantReadWriteLock是包含读锁和写锁的,从代码中能够看到:读锁和写锁之间是存在一些关系的,具原创 2022-12-07 10:47:36 · 465 阅读 · 0 评论 -
深入理解ThreadLocal源码
在之前介绍的多线程编程中,我们通常会利用synchronized或者各种lock来控制临界区资源的同步顺序,从而来解决线程安全问题。这实际是一种时间换空间的优化。线程安全问题的核心就是多个线程会对同一个临界区资源进行操作。ThreadLocal则是采用的是空间换时间的思想,让每个线程都拥有自己的共享资源,各自使用各自的,这样就不会出现线程安全问题。ThreadLocal意为“本地变量”,也就是达到人手一份的效果,不会出现竞争的情况。但是这种方式的缺点就是消耗的内存会大很多。原创 2022-12-01 16:15:35 · 401 阅读 · 0 评论 -
Java并发编程知识点总结(十二)——Condition中await和signal通知机制
线程A处于同步队列中,竞争中获得锁线程A在执行过程中调用Condition.await()方法,线程A释放锁,进入到condition条件队列中当线程A成为条件队列头部时,并且其他线程调用signal方法时,就会进入到同步队列的尾部进行排队线程A重新尝试获得锁。原创 2019-09-10 16:21:30 · 1936 阅读 · 2 评论 -
Java并发编程知识点总结(十三)——LockSupport方法总结
(一)、LockSupport概述我们在前面分析ReentrantLock以及Condition通信机制的时候多次使用到LockSupport.park()以及LockSupport.unpark()方法。LockSupport是用来阻塞线程的工具,park()方法用来阻塞线程,unpark()方法用来唤醒线程。LockSupport是不支持重入的,每一条线程都会对应一个许可,如果这个许可可用...原创 2019-09-10 17:01:43 · 274 阅读 · 0 评论 -
Java并发编程知识点总结(十四)——ThreadLocal实现原理
我本来想自己总结一下ThreadLocal以及关于内存泄漏的知识。但是可能是自己水平不够,写出来感感觉没有很好,这里推荐一个大佬的两篇文章吧,写得很好,我就是通过这两篇文章了解清楚的。1、并发容器之ThreadLocal2、一篇文章,从源码深入详解ThreadLocal内存泄漏问题...原创 2019-09-11 22:13:29 · 393 阅读 · 0 评论 -
Java并发编程知识点总结(十五)——BlockingQueue的各种实现
(一)、生产者-消费者问题队列通常被视作线程间操作数据的容器,生产者将“生产”出来的数据放置在数据容器中,消费者只需要在“数据容器”中获取数据即可。阻塞队列(BlockingQueue)被广泛使用在“生产者-消费者”问题中,其原因是BlockingQueue提供了可阻塞的插入和可阻塞的移除方法。当队列容器满了,插入线程会被阻塞,直到队列容器空出位置。当队列容器空了,移除线程会被阻塞,直到队列容器...原创 2019-09-12 12:31:19 · 241 阅读 · 0 评论 -
Java并发编程知识点总结(十六)——ArrayBlockingQueue源码浅析
(一)、概述上一篇文章中,我们介绍了阻塞队列的接口BlockingQeue,这一篇我们来介绍一下ArrayBlockingQueue的具体实现。阻塞队列通常用于生产者——消费者的模式中,当阻塞队列为空时,获取数据的线程会被阻塞,当阻塞队列满的时候,插入数据的线程也会被阻塞。下面我们来看一下ArrayBlockingQueue的具体实现。(二)、成员变量 //用来存放数据的数组 ...原创 2019-09-16 17:26:05 · 233 阅读 · 0 评论 -
Java并发编程知识点总结(十七)——LinkedBlockingQueue源码浅析
(一)、概述上一篇文章中我们介绍了ArrayBlockingQueue的具体实现,这一篇我们将介绍一个差不多的阻塞队列,不过是使用链表实现的LinkedBlockingQueue。LinkedBlockingQueue是使用两把ReentrantLock实现的,分别是takeLock(用于保证取出数据安全)、putLock(用于保证插入数据安全)。我们通过上一篇了解到ArrayBlockingQ...原创 2019-09-16 17:52:48 · 197 阅读 · 0 评论 -
Java并发编程知识点总结(十八)——线程池浅析
(一)、什么是线程池?线程池和数据库的连接池是比较类似的,当需要线程进行工作时,就从线程池中获取一个空闲的线程。当完成工作后,将线程返回到线程池中,供他人使用。(二)、为什么要使用线程池?线程虽然是一个轻量级的工具,但是创建和关闭依然需要花费一定的时间。如果每一个小任务都创建一个线程,那么很有可能创建和销毁线程的时间会大于实际工作时间,这样得不偿失。线程本身会占据一定的内存空间,所以可...原创 2019-09-17 16:13:01 · 329 阅读 · 1 评论 -
Java并发编程知识点总结(十九)——FutureTask的应用
FutureTask的应用场景主要是一个线程需要等待另一个线程的时候可以使用,FutureTask的get()方法会使当前线程阻塞,直到目标线程完成任务返回结果,才会继续往下执行。FutureTask最大的特点就是支持取消任务。如下图所示:针对run()方法的三种状态,针对run()方法的三种状态,原创 2019-09-17 17:36:28 · 496 阅读 · 1 评论 -
Java并发编程知识点总结(二十)——Atomic包
(一)、Atomic包简介Atomic包位于java.util.concurrent中,这个包主要是用来保证操作的原子性的,与Synchronized不同,Atomic采用的是乐观锁策略,而不是Synchronized采用的悲观锁策略。Atomic包中主要采用的是CAS操作进行更新数据,这样可以保证安全性。(二)、CAS操作CAS其实是CompareAndSwap的缩写,简单理解就是使用实际...原创 2019-09-17 22:37:44 · 331 阅读 · 0 评论 -
Java并发面试知识点汇总(超详细!)
Java并发编程知识点总结(一)——并发编程基础知识Java并发编程知识点总结(二)——线程的状态Java并发编程知识点总结(三)——Java内存模型以及Happens-Before原则Java并发编程知识点总结(四)——Synchronized实现原理以及优化Java并发编程知识点总结(五)——volatile实现原理Java并发编程知识点总结(六)——多线程下的final关键字Java并发编程知识点总结(七)——原子性、有序性、可见性Java并发编程知识点总结(八)——AQS源码分析之独占原创 2019-09-18 10:53:20 · 3399 阅读 · 1 评论 -
Java并发编程知识点总结(二十二)——各种并发工具类详解
假设学校规定必须全部的学生到齐,老师才能上课。老师首先来到教室,这时班上的同学都还没有来,老师设置计数器为50,进行逐一倒数,并执行等待方法await()。然后同学们相继到达教室,计数器的值也就一直在递减。最后,全班同学都到达了,那么计数器也就减为0了,这时老师就无需等待了,可以继续执行任务。原创 2019-09-18 12:24:17 · 476 阅读 · 0 评论 -
Java并发编程知识点总结(十一)——ReentrantLock实现原理
ReentrantLock意思为可重入锁,也就是能够多重加锁。并且加了多少次锁,也必须对应解锁多少次。此外,ReentrantLock支持公平锁和非公平锁,是基于AQS进行实现的。【基本功】不可不说的Java“锁”事公平锁:按照AQS的FIFO的同步队列的时间顺序获取锁,不会存在饥饿现象。非公平锁:有可能刚刚释放锁的线程又重新获得锁,可能会出现线程饥饿现象。下面我们来看下ReetrantLock和synchronizer之间的对比,如下图:AQS中实现了独占锁和共享锁的框架。原创 2019-09-08 11:26:49 · 811 阅读 · 0 评论 -
Java并发编程知识点总结(十)——Java中的Lock概述
(一)、Lock概述在Java SE5之后,出现了Lock接口。下面举一个简单的例子。 ReentrantLock lock = new ReentrantLock(); lock.lock(); try { //do something }finally { lock.unlock(); ...原创 2019-09-08 10:01:32 · 316 阅读 · 0 评论 -
Java并发编程知识点总结(九)——AQS源码分析之共享锁
(一)、概述这篇文章将会分析AQS源码之共享锁,我在上一篇文章中以及分析过AQS的独占锁以及AQS的底层实现原理,如果还没有看过的朋友,建议先看一下,因为这样理解共享锁会更加容易。共享锁:允许在同一时刻多个线程持有锁。**共享锁的特点:**当一个共享锁的线程被唤醒,那么它同时也会唤醒在同步队列中的下一个线程,如果这个线程也是等待共享锁的话。但是如果下一个线程在等待的是独占锁的话,那是无法获取...原创 2019-09-07 21:54:25 · 419 阅读 · 0 评论 -
Java高并发实战——同步控制工具
(1)、重入锁(ReentrantLock)重入锁使用java.util.concurrent.locks.ReentrantLock,下面是简单的使用案例public class ReenterLock implements Runnable { public static ReentrantLock lock = n...原创 2019-07-13 20:22:55 · 127 阅读 · 0 评论 -
JAVA高并发实战——线程复用:线程池
(一)、什么是线程池在线程池中,总有那么几个活跃的线程。当你需要使用线程时,可以从池子中随便拿一个空间线程,当完成工作时,并不着急关闭线程,而是将这个线程退回到线程池中,方便其他人使用。创建线程变成了从线程池获得空闲线程,关闭线程变成了向线程池归还线程。(二)、不要重复发明轮子:JDK对线程池的支持下面是Executors框架结构图ThreadPoolExecutor表示一个线...原创 2019-07-14 09:56:29 · 305 阅读 · 0 评论 -
JAVA高并发实战——走入并行世界
一、几个基本概念 1、同步(Synchronous)和异步(Asynchronous)同步和异步通常用来形容一次方法调用同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后继的行为异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者就可以继续后继的操作。异步方法不会阻碍调用者的工作 2、并...原创 2019-07-12 10:55:42 · 409 阅读 · 0 评论 -
Java并发编程知识点总结(一)——并发编程基础知识
(一)、必须知道的几个概念同步和异步同步和异步都是用来形容一次方法调用。主要的区别是同步方法调用一旦开始,就必须等待调用的方法返回之后才能继续执行下面的程序。而异步调用则无需等待调用的方法返回,调用之后就可以立即执行下面的语句,当调用的方法返回之后会通知调用者。举个例子,你去商场购买空调,你和销售员说你想买一台空调,于是销售员就安排师傅把空调送到你家里去,等空调安装上了你才付钱,这个是同步调用...原创 2019-08-28 20:48:21 · 1339 阅读 · 0 评论 -
Java并发编程知识点总结(三)——Java内存模型以及Happens-Before原则
Java内存模型在说线程安全之前,我们先来看一下什么是线程不安全:线程不安全的情况是出线在多线程中的,当多个线程对同一共享资源进行修改操作时,就有可能出线程序的执行结果不一致,那么这就是线程不安全。如果对共享资源只进行读的操作,那么并不会出线线程不安全,但是写的操作会因为线程之间的一些不可见性而导致线程不安全。那么什么是线程安全呢?当多个线程访问同一个对象的时候,如果不用考虑这些线程...原创 2019-09-02 16:44:57 · 495 阅读 · 1 评论 -
Java并发编程知识点总结(二)——线程的状态
(一)、新建线程的三种方式继承自Thread类public class Thread1 { public static void main(String[] args) { Thread thread = new Thread(){ @Override public void run() { ...原创 2019-08-31 16:06:36 · 596 阅读 · 3 评论 -
主线程Main先结束还是子线程先结束?
今天在复习并发基础的时候,发现一个很有意思的问题,到底是主线程Main先结束呢,还是子线程先结束呢?这个主要分为两种情况,让我们来看一下。情况一:没有设置子线程为守护进程public class Thread3 { public static void main(String[] args) throws InterruptedException { //获得主线程...原创 2019-08-31 14:38:07 · 2799 阅读 · 0 评论 -
Java并发编程知识点总结(四)——Synchronized实现原理以及优化
synchronized原理我们可以知道线程的安全问题主要来自于Java内存模型的设计,也就是主内存和各工作内存之间而导致的内存可见性问题,以及重排序导致的问题。synchronized关键字可以使得线程依次排队操纵共享变量。但是这种机制会导致效率比较低下,并发程度低。下面我们就具体来看一下synchronized关键字(二)、synchronized实现原理2.1 synchroized的作用范围...原创 2019-09-04 17:00:58 · 936 阅读 · 0 评论 -
Java并发编程知识点总结(五)——volatile实现原理
volatile实现原理volatile可以说说jvm提供的最轻量级的同步机制。被volatile修饰的变量能够保证每个线程能够获取该变量的最新值,从而避免数据出现脏读的现象。(二)、volatile实现原理volatile是如何实现的?下面举一个简单的例子instacne = new instance();//instance是volatile变量在生成汇编代码的时候jv...原创 2019-09-05 15:48:12 · 589 阅读 · 0 评论 -
Java并发编程知识点总结(六)——Java中的final关键字
final关键字原创 2019-09-05 21:56:45 · 1601 阅读 · 0 评论 -
Java并发编程知识点总结(七)——原子性、有序性、可见性
synchronized:原子性、有序性、可见性volatile:有序性、可见性。三大性质总结:原子性,有序性,可见性。原创 2019-09-06 09:08:06 · 1045 阅读 · 0 评论 -
Java并发编程知识点总结(八)——AQS源码分析之独占锁
(一)、AQS概述AbstractQueuedSynchronizer简称AQS,它是java.util.concurrent包中,它提供了一套完整的同步编程框架。我们常用的ReentrantLock、CountDownLatch都是基于AQS实现的。AQS的实现分为两种形式,一种是独占锁,另一种则是共享锁。独占锁:每次只能有一个线程持有锁。我们比较熟悉的ReentrantLock就是通过...原创 2019-09-07 20:20:49 · 509 阅读 · 0 评论 -
JAVA高并发实战——Java并行程序基础
一、线程与进程的区别线程就是轻量级的进程,是程序执行的最小单位。使用多线程而不是用多进程去进行并发程序的设计,是因为线程间的切换和调度的成本远远小于进程。线程的生命周期1、NEW状态:刚刚创建线程,线程还没开始执行。调用start(),线程开始执行2、RUNNABLE状态:表示线程所需的一切资源已经准备好了。3、BLOCKED状态:如果线程在执行过程中遇到了synchronized同...原创 2019-07-13 14:33:53 · 159 阅读 · 0 评论