![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
thread
文章平均质量分 94
我只是文章的搬运工
那个少年~
这个作者很懒,什么都没留下…
展开
-
AQS系列(2)-独占锁的释放
开始之前先提一句,JAVA的内置锁在退出临界区之后是会自动释放锁的,但是ReentrantLock这样的显示锁是需要自己显示释放的,所以在加锁之后一定不要忘记在finally快中进行显示的锁释放:Lock lock = new ReentrantLock();...lock.lock();try { // 更新对象 //捕获异常} finally { lock.unlock();}ReentrantLock的锁释放由于锁的释放操作对于公平锁和非公平锁都是一样的转载 2021-04-02 17:32:59 · 165 阅读 · 0 评论 -
AQS系列(1)-独占锁的获取
本篇我们以ReentrantLock的公平锁为例来详细看看使用AQS获取独占锁的流程本文中的源码基于JDK1.8.Java并发工具类的三板斧状态,队列,CAS每当我们学习一个java并发变成工具的时候,我们首先要抓住这三点状态:一般是一个state属性,它基本是整个工具的核心,通常整个工具都是在设置和修改状态,很多方法的操作都依赖于当前状态是什么。由于状态是全局共享的,一般会被设置成volatile类型,以保证已修改的可见性。 队列:队列通常是一个等待集合。大多数以链表的形式实现.转载 2021-04-02 16:59:59 · 200 阅读 · 0 评论 -
创建多少个线程合适?
创建多少个线程,一般我们根据场景来进行讨论CPU密集型程序一个完整请求,I/O操作可以在很短时间内完成,cpu还有很多运算要处理,也就是说CPU计算的比例占很大一部分假如我们要计算1+2+3+4+....+100亿的总和,很明显,这就是一个CPU密集型程序。在单核CPU下,如果我们创建4个线程来分段计算,即:线程1计算【1,25亿】 ...以此类推 线程4计算【75亿,100亿】我们来看下图他们会发生什么?由于是单核CPU,所有线程都在等待CPU时间片。按照理想情况来看,四转载 2021-02-07 15:44:44 · 1557 阅读 · 3 评论 -
24.线程系列- google提供的一些好用的并发工具类
关于并发方面,juc已帮我们提供了很多好用的工具,而谷歌在此基础上做了扩展,使并发更容易,这些工具放在guava.jar包中。本文演示几个简单的案例,见一下guava的效果。guava maven配置<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.0-jre<转载 2020-12-22 14:13:44 · 564 阅读 · 0 评论 -
23.线程系列- 高并发中计数器的实现方式
本文主要内容4中方式实现计数器功能,对比其性能 介绍LongAdder 介绍LongAccumulator需求:一个jvm中实现一个计数器功能,保证多线程情况下数据正确性我们来模拟50个线程,每个线程对计数器递增100万次,最终结果应该是5000万我们使用4中方式实现,看一下其性能,然后引出为什么需要使用LongAdder,LongAccumulator。方式1:synchronized方式实现public class Demo1 { static int count =转载 2020-12-22 13:18:50 · 338 阅读 · 0 评论 -
22.线程系列- 获取线程执行结果的方式
在一个线程中需要获取其他线程执行的结果,能想到几种方式?各有什么优缺点?结合这个需求,我们使用6中方式,来对之前学过的知识点做一个回顾,加深记忆。方式1:Thread的join方法实现代码:public class Demo1 { //用于封装结果 static class Result<T> { T result; public T getResult() { return result;转载 2020-12-22 10:49:24 · 905 阅读 · 0 评论 -
21.线程系列- JUC工具类CompletableFuture
CompletableFuture是java8新增的一个类,算是对Future的一种增强,用起来很方便,也是会经常用到的一个工具类CompletionStage接口CompletionStage代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段 一个阶段的计算执行可以是一个Function,Consumer或者Runnable。比如:stage.thenApply(x -> square(x)).thenAccept(x -> System.out.print(x)转载 2020-12-21 18:31:30 · 282 阅读 · 0 评论 -
20.线程系列- 高并发中常见的限流方式(并发控制,漏桶,令牌桶(RateLimiter))
本文内容介绍常见的限流算法 通过控制最大并发数来进行限流 通过漏桶算法来进行限流 通过令牌桶算法来进行限流 限流工具类RateLimiter常见的限流算法通过控制最大并发数来进行限流 通过漏桶算法来进行限流 通过令牌桶算法来进行限流通过控制最大并发数来进行限流以秒杀业务为例,100万人抢购,100万人同时发起请求,最终能抢到的人也就是前面几个人,后面的基本上都没有希望。那么我们可以通过控制并发数来实现,比如并发控制在10个,其他超过并发数的请求全部拒绝,提示秒杀失败,请稍后重试。转载 2020-12-21 16:26:27 · 700 阅读 · 0 评论 -
19.线程系列- 实战篇,接口性能的简单提升
案列讲解电商app都有用过吧,商品详情页,需要给他们提供一个接口获取商品相关信息:1,商品基本信息(名称,价格,库存,会员价格等)2,商品图片列表3,商品描述信息等等数据库中我们用了3张表存储上面的信息: 商品基本信息表:t_goods(字段:id【商品id】、名称、价格、库存、会员价格等) 商品图片信息表:t_goods_imgs(字段:id、goods_id【商品id】、图片路径),一个商品会有多张图片 商品描述信息表:t_goods_ext(字段:id,g转载 2020-12-21 14:10:22 · 124 阅读 · 0 评论 -
18.线程系列- JUC中的阻塞队列
本文内容掌握Queue,BlockingQueue接口中常用的方法 介绍6种阻塞队列,以及相关场景示例 重点掌握4种常用的阻塞队列Queue接口队列是一种先进先出FIFO的数据结构,java中用Queue接口来表示队列Queue接口中定义了6个方法:public interface Queue<E> extends Collection<E> { boolean add(e); boolean offer(E e); E remove(转载 2020-12-21 13:53:37 · 129 阅读 · 0 评论 -
17.线程系列- ThreadLocal、InheritableThreadLocal(通俗易懂)
本文的内容需要解决的问题 介绍ThreadLocal 介绍InheritableThreadLocal需要解决的问题目前java开发web系统一般有3层,controller,service,dao,请求到达controller。controller调用service,service调用dao,然后进行处理我们写一个简单的列子,有3个方法分别模拟controller,service,dao。代码如下:public class Demo { static AtomicInte转载 2020-12-21 09:53:42 · 146 阅读 · 0 评论 -
16.线程系列- JUC中原子类
本文主要内容JUC中的原子类介绍 介绍基本类型原子类 介绍数组类型原子类 介绍引用类型原子类 介绍对象属性修改相关原子类预备知识JUC中的原子类都是依靠volatile,cas,Unsafe类配置来实现的,需要了解的请看之前的线程系列的文章,都有详解JUC中原子类介绍什么是原子操作?atomic翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里atomic是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作转载 2020-12-18 11:09:51 · 181 阅读 · 0 评论 -
15.线程系列- JUC底层工具类Unsafe
本文的内容Unsafe基本介绍 获取Unsafe实例 Unsafe中的CAS操作 Unsafe中原子操作相关方法介绍 Unsafe中线程调度先关方法介绍 park和unpark示例 Unsafe锁示例 Unsafe中对volatile的支持基本介绍最新我们一直在学习java高并发,java高并发中主要涉及到类位于juc包中,juc中大部分类都是依赖于Unsafe来实现的,主要用到了Unsafe中的CAS,线程挂起,线程恢复等相关功能。所以如果打算深入了解juc原理,必须先了解Unsa转载 2020-12-17 16:20:51 · 87 阅读 · 0 评论 -
14.线程系列- CAS,你需要知道的东西
本文主要内容从网站计数器实现中一步步引出CAS操作 介绍java中CAS以及CAS可能存在的问题 悲观锁和乐观锁的一些介绍以及数据库乐观锁的一个常见示例 使用java中的原子操作实现网站计数器功能我们需要解决的问题方式1:需求:我们开发了一个网站,需要对访问量进行统计,用户每次发一次请求,访问量+1,如何实现?下面我们来模仿有100个人同时访问,并且每个人对网站发起10次请求,最后总访问次数应该是1000次。我们实现访问如下:public class demo1 {转载 2020-12-17 14:55:51 · 123 阅读 · 0 评论 -
13.线程系列- JUC中的Executor详解2
本文的内容ExecutorCompletionService出现的背景 介绍CompletionService接口以及常见的方法 介绍ExecutorCompletionService类以及其原理 实例:执行一批任务,然后消费执行结果 实例:异步执行一批任务,有一个完成则立即返回,其他取消需要解决的问题举个例子:买新房了,然后在往下下单买冰箱,洗衣机,电器商家不同,所以送货耗时不一样,然后等他们送货,快递只愿意送到楼下,然后我们自己将其搬到家中。public class Demo转载 2020-12-17 11:00:19 · 118 阅读 · 0 评论 -
12.线程系列- JUC中的Executor详解1
Executors框架介绍Executor框架主要包含3部分内容:任务相关的:包含被执行的任务要实现的接口:Runnable接口或Callable接口 任务执行相关的:包含任务执行机制的核心接口Executor,以及继承自Executor的ExecutorService接口。Executor框架中有两个关键的类实现了ExecutorService接口:ThreadPoolExecutor和ScheduleThreadPoolExecutor 异步结算结果相关的:包含接口Future和实现Futu转载 2020-12-16 16:40:51 · 241 阅读 · 0 评论 -
11.线程系列- 线程池
什么是线程池大家用jdbc操作过数据库应该知道,操作数据库需要和数据库建立连接,拿到连接之后才能操作数据库,用完之后销毁。数据库连接的创建和销毁其实是比较耗时的,真正和业务相关的操作耗时是比较短的。每个数据库操作之前都需要创建连接,为了提升系统性能,后来出现了数据库连接池,系统启动的时候,先创建很多连接放在池子里面,使用的时候,直接从连接池中获取一个,使用完毕之后返回到池子里面,继续给其他需要者使用,这其中就省去创建连接的时间,从而提升了系统整体的性能。线程池和数据库连接池的原理也差不多,创建线程去转载 2020-12-16 14:56:58 · 246 阅读 · 0 评论 -
10.线程系列- JUC中的CyclicBarrier
CyclicBarrier简介CyclicBarrier通常称为循环屏障。它和CountDownLatch很相似,都可以使线程先等待然后再执行。不过CountDownLatch是使一批线程等待另一批线程执行完后再执行;而CyclicBarrier只是使等待的线程达到一定数目后再让它们继续执行。故而CyclicBarrier内部也有一个计数器,计数器的初始值在创建对象时通过构造参数指定,如下所示:public CyclicBarrier(int parties) { this(parties转载 2020-12-15 18:20:18 · 111 阅读 · 0 评论 -
9.线程系列- JUC中的Semaphore
Semaphore常用场景:限流举个例子:比如有个停车场,有5个空位,门口有个门卫,手中5把钥匙分别对应5个车位上面的锁,来一辆车,门卫会给司机一把钥匙,然后进去找到对应的车位停下来,出去的时候司机将钥匙归还给门卫。停车场生意比较好,同时来了100两车,门卫手中只有5把钥匙,同时只能放5辆车进入,其他车只能等待,等有人将钥匙归还给门卫之后,才能让其他车辆进入。上面的例子中门卫就相当于Semaphore,车钥匙就相当于许可证,车就相当于线程Semaphore主要方法Semaphore(int pe转载 2020-11-09 14:12:50 · 213 阅读 · 0 评论 -
8.线程系列- JUC中等待多线程完成的工具类CountDownLatch
本片内容介绍CountDownLatch及使用场景提供几个示例介绍CountDownLatch的使用手写一个并行处理任务的工具类假如有这样一个需求,当我们需要解析一个Excel里多个shee的数据时,可以考虑使用多线程,每个线程解析一个sheet里的数据,等到所有的sheet都解析完之后,程序需要统计解析总耗时。分析一个:解析每个sheet耗时可能不一样,总耗时就是最长耗时的那个操作。我们能够想到的最简单的做法是使用join,代码如下:public class ThreadDemo13 {转载 2020-11-09 11:12:51 · 178 阅读 · 0 评论 -
7.线程系列- JUC中的LockSupport工具类
本文主要内容讲解3中让线程等待和唤醒的方法,每种方法配合具体的实例介绍LockSupport主要用法对比3中方式,了解他们之间的区别LockSupport位于juc包下,算是juc中一个基础类,juc中很多地方都会使用LockSupport关于线程等待、唤醒的方法,前面的文章中我们已经讲过2种了:使用Object中的wait(),notify()方法让线程等待,唤醒使用juc包中的Condition的await(),signal()方法唤醒线程使用Object类中的方法实现线程等待和转载 2020-11-06 14:54:21 · 110 阅读 · 0 评论 -
6.线程系列- JUC中的Condition对象
Condition使用简介任何一个java对象都天然继承于Object类,在线程间实现通信的往往会应用到Objetc的几个方法,比如wait(),notify(),notifyAll()几个方法实现等待或通知机制,同样的,在java Lock体系下依然会有同样的方法实现等待/通知机制。从整体上来看Object的wait和notify/notify是与对象监视器配合完成线程间的等待/通知机制,而Condition与Lock配合完成等待通知机制,前者是java底层级别的,后者是语言级别的,具有更高的可控制性转载 2020-11-05 17:32:25 · 316 阅读 · 1 评论 -
5.线程系列- ReentrantLock重入锁
synchronized的局限性synchronized是java内置的关键字,它提供了一种独占的加锁方式。synchronized的获取和释放锁由jvm实现,用户不需要显示的释放锁,非常方便,然而synchronized也有一定的局限性:当线程尝试获取锁的时候,如果获取不到锁会一直阻塞,在这阻塞的过程,用户无法控制如果获取锁的线程进入休眠或者阻塞,除非当前线程异常,否则其他线程尝试获取锁必须一直等待。JDK1.5之后发布,加入了Doug Lea实现的java.util.concurrent包。转载 2020-11-03 15:37:01 · 128 阅读 · 1 评论 -
4.线程系列- synchronized底层原理
了解完synchronized的基本含义及其使用方式后,下面我们将进一步深入理解synchronized的底层实现原理。synchronized底层语义原理java虚拟机中的同步(Synachronization)基于进入和退出管程(Monitor)对象实现,无论是显示同步(有明确的monitorenter 和monitorexit 指令,即同步代码块)还是隐式同步都是如此。在java语言中,同步用的最多的地方可能是被synchronized 修饰的同步方法。同步方法并不是由monitorenter 和转载 2020-11-02 14:50:37 · 100 阅读 · 0 评论 -
3.线程系列- 线程安全和synchronized关键字
什么是线程安全当多个线程去访问同一个类(对象或者方法)的时候,该类都能表现出正常的行为(与自己预想的结果一致),那我们就可以说这个类是线程安全的看一段代码:public class Demo1 { static int num = 0; public static void m1() { for (int i = 0; i < 10000; i++) { num++; } } public static转载 2020-11-02 10:27:07 · 82 阅读 · 0 评论 -
2.线程系列- volatile与Java内存模型
先看个案例:public class ThreadDemo3 { static boolean flag = true; static class T1 extends Thread{ @Override public void run() { System.out.println("线程" + this.getName() + " in"); while (flag){ }转载 2020-10-30 14:51:10 · 58 阅读 · 0 评论 -
1.线程系列- 线程的基本操作
新建线程新建线程很简单,只需要使用new关键字创建一个线程对象,然后调用它的start()启动线程即可。Thread t1 = new Thread();t1.start();那么线程start()之后,会干什么呢?线程有个run()方法,start()会创建一个新的线程并让这个线程执行run()方法。这里需要主要,下面代码也能通过编译,也能正常执行。但是,却不能新建一个线程,而是在当前线程中调用run()方法,将run方法作为一个普通的方法进行调用。Thread t1 = new Threa转载 2020-10-30 14:17:03 · 494 阅读 · 0 评论 -
线程高频面试题
1、Java中实现多线程有几种方法继承Thread类;实现Runnable接口;实现Callable接口通过FutureTask包装器来创建Thread线程;2、如何停止一个正在运行的线程使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。public class ServerThread extends Thread { //volatile修饰符用来保证...转载 2020-04-12 09:18:44 · 141 阅读 · 0 评论 -
对锁以及sychronize的理解
基础知识之一:锁的类型按照其性质分类1)公平锁/非公平锁公平锁是指多个线程按照申请锁的顺序来获取锁。非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。有可能,会造成优先级反转或者饥饿现象。对于Java ReentrantLock而言,通过构造函数指定该锁是否是公平锁,默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。对于Synchroni...转载 2020-04-10 11:19:25 · 818 阅读 · 0 评论