
java 并发编程
文章平均质量分 90
11
fastjson_
这个作者很懒,什么都没留下…
展开
-
synchronized 加锁 this 和 class 的区别
通过以上 4 个示例我们可以得出结论,当使用 synchronized 加锁 class 时,无论共享一个对象还是创建多个对象,它们用的都是同一把锁,而使用 synchronized 加锁 this 时,只有同一个对象会使用同一把锁,不同对象之间的锁是不同的。。原创 2023-03-21 14:05:17 · 263 阅读 · 0 评论 -
java创建线程的三种方式
一、Java中创建线程主要有三种方式:1、继承Thread类创建线程类定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。 创建Thread子类的实例,即创建了线程对象。 调用线程对象的start()方法来启动该线程。public class FirstThreadTest extends Thread{ int i = 0; //重写run方法,run方法的方法体就是现场执行体原创 2021-10-06 16:43:38 · 669 阅读 · 0 评论 -
Executor 线程池框架详解
一、什么是Executor框架?我们知道线程池就是线程的集合,线程池集中管理线程,以实现线程的重用,降低资源消耗,提高响应速度等。线程用于执行异步任务,单个的线程既是工作单元也是执行机制,从JDK1.5开始,为了把工作单元与执行机制分离开,Executor框架诞生了,他是一个用于统一创建与运行的接口。Executor框架实现的就是线程池的功能。对比...原创 2021-10-06 09:39:27 · 675 阅读 · 1 评论 -
线程池原理
熟悉 Java 多线程编程的同学都知道,当我们线程创建过多时,容易引发内存溢出,因此我们就有必要使用线程池的技术了。1、线程池的优势总体来说,线程池有如下的优势:(1)降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。(2)提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。(3)提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。2、线程池的使用线程池的真正实原创 2021-10-04 16:37:47 · 193 阅读 · 0 评论 -
Java中的并发工具类
一、等待多线程完成的CountDownLatch需求场景:当我们需要解析一个Excel里多个sheet的数据,此时可以考虑使用多线程,每个线程解析一个sheet里的数据,等到sheet都解析完之后,程序需要提示解析完成。当然我们可以使用join方法,join用于让当前线程等待join线程执行结束。在JDK1.5之后的并发包中提供的CountDownLatch也可以实现join的功能。CountDownLatch允许一个或多个线程等待其他线程完成操作。CountDownLatch的构造函数接收一个i原创 2021-10-03 09:26:45 · 1166 阅读 · 0 评论 -
java并发之阻塞队列LinkedBlockingQueue
LinkedBlockingQueue的实现原理剖析ArrayList和ArrayBlockingQueue一样,内部基于数组来存放元素,而LinkedBlockingQueue则和LinkedList一样,内部基于链表来存放元素。LinkedBlockingQueue实现了BlockingQueue接口,这里放一张类的继承关系图LinkedBlockingQueue不同于ArrayBlockingQueue,它如果不指定容量,默认为Integer.MAX_VALUE,也就是无界队列。所以.原创 2021-10-02 16:56:09 · 2933 阅读 · 0 评论 -
volatile关键字解析
volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用volatile关键字的场景。一、内存模型的相关概念大家都知道,计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU原创 2021-10-02 11:06:23 · 297 阅读 · 0 评论 -
Java16个原子类介绍
关于原子类个数说明在JDK7包括7之前,java原子类有12个,图片如下在JDK8时出现了4个原子操作类,分别是如下图片所示原子更新基本类型类使用原子的方式更新基本类型,Atomic包提供了以下3个类。AtomicBoolean: 原子更新布尔类型。 AtomicInteger: 原子更新整型。 AtomicLong: 原子更新长整型。以上3个类提供的方法几乎一模一样,以AtomicInteger为例进行详解,AtomicIngeter的常用方...原创 2021-10-02 10:09:52 · 8178 阅读 · 0 评论 -
java并发之阻塞队列ArrayBlockingQueue
一、ArrayBlockingQueueArrayBlockingQueue 是一个用数组实现的有界阻塞队列,其内部按先进先出的原则对元素进行排序,其中put方法和take方法为添加和删除的阻塞方法,下面我们通过ArrayBlockingQueue队列实现一个生产者消费者的案例,通过该案例简单了解其使用方式代码比较简单, Consumer 消费者和 Producer 生产者,通过ArrayBlockingQueue 队列获取和添加元素,其中消费者调用了take()方法获取元素当队列没有元素就阻塞,生原创 2021-10-01 16:45:22 · 4010 阅读 · 0 评论 -
java并发之阻塞队列DelayQueue
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。阻塞队列提供了四种处理方法:方法\处理方式 抛出异常 返回特殊值 一直阻塞 超时退出 插入方法 add(e) offer(e)原创 2021-09-30 17:10:02 · 526 阅读 · 0 评论 -
并发容器之ConcurrentLinkedQueue详解
简介在并发编程中我们有时候需要使用线程安全的队列。如果我们要实现一个线程安全的队列有两种实现方式一种是使用阻塞算法,另一种是使用非阻塞算法。使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现,而非阻塞的实现方式则可以使用循环CAS的方式来实现,下面我们一起来研究下Doug Lea是如何使用非阻塞的方式来实现线程安全队列ConcurrentLinkedQueue的。ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进原创 2021-09-30 09:34:37 · 1767 阅读 · 0 评论 -
Java并发之显式锁和隐式锁的区别
在Java并发编程中,锁有两种实现:隐式锁和显示锁两者的区别是什么?所谓的显式锁和隐式锁的区别也就是说说Synchronized(下文简称:sync)和lock(下文就用ReentrantLock来代之lock)的区别。本文主要内容:将通过六个方面详细介绍sync和lock的区别。Java中隐式锁:synchronized;显式锁:lock一:出身不同从sync和lock的出身(原始的构成)来看看两者的不同。Sync:Java中的关键字,是由JVM来维护的。是JVM层面的锁。L.原创 2021-09-25 11:20:49 · 232 阅读 · 0 评论 -
java Condition类的详细介绍
一 、condition 介绍及demo Condition是在java 1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition的await()、signal()这种方式实现线程间协作更加安全和高效。因此通常来说比较推荐使用Condition,阻塞队列实际上是使用了Condition来模拟线程间协作。Condition是个接口,基本的方法就是await()和signal()方法;原创 2021-09-24 17:03:11 · 4508 阅读 · 1 评论 -
隐式锁synchronized实现原理
前言:线程安全是并发编程中的重要关注点,应该注意到的是,造成线程安全问题的主要诱因有两点,一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据。因此为了解决这个问题,我们可能需要这样一个方案,当存在多个线程操作共享数据时,需要保证同一时刻有且只有一个线程在操作共享数据,其他线程必须等到该线程处理完数据后再进行,这种方式有个高尚的名称叫互斥锁,即能达到互斥访问目的的锁,也就是说当一个共享数据被当前正在访问的线程加上互斥锁后,在同一个时刻,其他线程只能处于等待的状态,直到当前线程处理完毕释放该锁。转载 2021-09-24 12:13:25 · 357 阅读 · 0 评论 -
重入锁(ReentrantLock)和读写锁(ReentrantReadWriteLock)
重入锁(ReentrantLock)重入锁ReentrantLock,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁。除此之外,该锁的还支持获取锁时的公平和非公平性选择。对于独占锁(Mutex),考虑如下场景:当一个线程调用Mutex的lock()方法获取锁之后,如果再次调用lock()方法,则该线程将会被自己所阻塞,原因是Mutex在实现tryAcquire(int acquires)方法时没有考虑占有锁的线程再次获取锁的场景,而在调用tryAcquire(int acq原创 2021-09-23 16:45:28 · 3511 阅读 · 0 评论 -
显示锁LOCK和队列同步器(AQS)详解
队列同步器(AQS)队列同步器AbstractQueuedSynchronizer(以下简称同步器),是用来构建锁或者其他同步组件的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作,并发包的作者(Doug Lea)期望它能够成为实现大部分同步需求的基础。队列同步器的基本结构同步器依赖内部的同步队列(一个FIFO双向队列)来完成同步状态的管理。同步队列中的节点(Node)用来保存"获取同步状态失败的线程"引用、等待状态以及前驱和后继节点。同步原创 2021-09-22 11:13:46 · 461 阅读 · 0 评论 -
java线程的中断(interrupt)
一个线程在未正常结束之前, 被强制终止是很危险的事情. 因为它可能带来完全预料不到的严重后果比如会带着自己所持有的锁而永远的休眠,迟迟不归还锁等。 所以你看到Thread.suspend, Thread.stop等方法都被Deprecated了那么不能直接把一个线程搞挂掉, 但有时候又有必要让一个线程死掉, 或者让它结束某种等待的状态 该怎么办呢?一个比较优雅而安全的做法是:使用等待/通知机制或者给那个线程一个中断信号, 让它自己决定该怎么办。这里我们理解线程中断的使用场景和使用时的注意事项,最后使原创 2021-09-22 10:21:38 · 4225 阅读 · 2 评论 -
Idea Intellij多线程调试
几天前遇到一个问题:在多线程调试的时候,一些断点会被跳过。比如像下面的代码:public static void main(String[] args) throws InterruptedException { new Thread() { // 断点0 @Override public void run() { System.out.println("1"); // 断点1 try {原创 2021-09-17 10:28:59 · 1942 阅读 · 0 评论 -
Java线程的6种状态及切换
Java中线程的状态分为6种1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。3. 阻塞(BLOCKED):表原创 2021-09-17 09:20:06 · 501 阅读 · 0 评论 -
java命令--jstack 工具
一、jstack介绍:jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 java 应用程序中线程堆栈信息。 jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生原创 2021-09-16 22:43:53 · 1356 阅读 · 0 评论 -
理解Java内存模型(JMM)
本篇的写作思路是先阐明Java内存区域划分、硬件内存架构、Java多线程的实现原理与Java内存模型的具体关系,在弄明白它们间的关系后,进一步分析Java内存模型作用以及一些实现手段理解Java内存区域与Java内存模型Java内存区域Java虚拟机在运行程序时会把其自动管理的内存划分为以上几个区域,每个区域都有的用途以及创建销毁的时机,其中蓝色部分代表的是所有线程共享的数据区域,而绿色部分代表的是每个线程的私有数据区域方法区(Method Area): ...转载 2021-09-15 13:23:44 · 7360 阅读 · 0 评论 -
Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用
一、ThreadPoolTaskExecutor本文采用 Executors 的工厂方法进行配置。1、将线程池用到的参数定义到配置文件中在项目的 resources 目录下创建 executor.properties 文件,并添加如下配置:# 异步线程配置# 核心线程数async.executor.thread.core_pool_size=5# 最大线程数async.executor.thread.max_pool_size=8# 任务队列大小async.executor.t原创 2020-11-17 14:58:34 · 1624 阅读 · 1 评论 -
Java中,两个请求同时访问一个action或method,代码的执行顺序是怎么样的
首先看文章之前你可以在脑海中模拟一下,两个请求并发访问一个方法,从浏览器到后台的大致流程是怎么样的,模拟的越详细越好。我相信很大一部分人可能都会被这个问题难住,不管是刚毕业的大学生,还是工作两三年的朋友们。可能我们平时太多的关注业务逻辑,关注各种炫酷的框架,亦或者是公司太忙,忙到我们没时间成长等等等,从而忽略了这些最基础的东西。不过可能正是因为这些最基础的东西,才是我们为什么薪资比别人低了一点,为什么机会比别人少了一点,为什么差距和别人越来越大。学而不思则罔,思而不学则殆。这个问题其实分两步原创 2020-10-15 14:22:19 · 1022 阅读 · 2 评论 -
线程本地变量 ThreadLocal
一、ThreadLocal介绍threadlocal是一个线程内部的存储类,可以在指定线程内存储数据,数据存储以后,只有指定线程可以得到存储数据。ThreadLocal 的作用是:提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂度。总结:1. 线程并发: 在多线程并发的场景下2. 传递数据: 我们可以通过ThreadLocal在同一线程,不同组件中传递公共变量3. 线程隔离: 每个线程的变量都是独原创 2020-05-15 15:27:18 · 550 阅读 · 0 评论