懒羊羊--搞点小技术
热爱代码,热爱程序
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
CompletableFuture常用用法及踩坑
如果不设置超时时间,运行上述代码时会发现,明明主线程执行完毕,异步线程没有直接报错,但异步线程的结果迟迟没有返回(假设调用的接口网络不通,且没有回TCP包,没有快速失败),也没有打印日志。注意点: CompletableFuture在本地测试的时候会发现,主线程执行完毕了,异步线程一直没有返回,这是因为如果使用java的主线程方法测试,那么运行结束后,程序就退出了,异步线程自然也就没有了。对于Web项目,调用该方法时,只是主线程结束,但程序没有退出,异步线程依旧可以运行。同时打印足量的日志方便排查。原创 2025-04-28 13:51:22 · 37 阅读 · 0 评论 -
CompletableFuture常用用法及踩坑
引用文章原创 2025-03-27 11:44:10 · 27 阅读 · 0 评论 -
EasyExcel并行导出多个excel文件并压缩下载
在SpringBoot应用中,采用同步方式导出Excel文件会导致服务器在生成文件期间阻塞,特别是在处理大量数据时,这种效率较低的方法会严重影响性能。为了解决这个问题,可以采用以下改进措施:首先将导出的数据进行拆分,然后利用CompletableFuture将导出任务异步化。相比之下,之前介绍过的《多线程+EasyExcel实现报表优雅导出》使用FutureTask实现的多线程导出方法也能达到类似的效果,但CompletableFuture提供了更简洁的API和更强大的功能,更适合现代并发编程的需求。原创 2024-11-19 12:33:21 · 385 阅读 · 0 评论 -
java高并发系列 - 第10天:线程安全和synchronized关键字
当多个线程去访问同一个类(对象或方法)的时候,该类都能表现出正常的行为(与自己预想的结果一致),那我们就可以所这个类是线程安全的。原创 2023-08-24 16:58:56 · 252 阅读 · 0 评论 -
java高并发系列 - 第11天:线程中断的几种方式
当一个线程处于被阻塞状态或者试图执行一个阻塞操作时,可以使用 Thread.interrupt()方式中断该线程,注意此时将会抛出一个InterruptedException的异常,同时中断状态将会被复位(由中断状态改为非中断状态)内部有循环体,可以通过一个变量来作为一个信号控制线程是否中断,注意变量需要volatile修饰文中的几种方式可以结合起来灵活使用控制线程的中断。原创 2023-08-23 11:07:31 · 226 阅读 · 0 评论 -
java高并发系列 - 第12天JUC:ReentrantLock重入锁
对比上面的代码,与关键字synchronized相比,ReentrantLock锁有明显的操作过程,开发人员必须手动的指定何时加锁,何时释放锁,正是因为这样手动控制,ReentrantLock对逻辑控制的灵活度要远远胜于关键字synchronized,上面代码需要注意lock.unlock()一定要放在finally中,否则,若程序出现了异常,锁没有释放,那么其他线程就再也没有机会获取这个锁了。输出结果中分析,t2获取到锁了,然后休眠了5秒,t1获取锁失败,t1打印了2条信息,时间相差3秒左右。原创 2023-08-21 15:45:53 · 225 阅读 · 0 评论 -
java高并发系列 - 第13天:JUC中的Condition对象
在了解Condition之前,需要先了解一下重入锁ReentrantLock,可以移步到。原创 2023-08-21 10:00:18 · 191 阅读 · 0 评论 -
java高并发系列 - 第14天:JUC中的LockSupport工具类,必备技能
LockSupport类可以阻塞当前线程以及唤醒指定被阻塞的线程。主要是通过park()和unpark(thread)方法来实现阻塞和唤醒线程的操作的。每个线程都有一个许可(permit),permit只有两个值1和0,默认是0。原创 2023-08-14 19:42:38 · 190 阅读 · 0 评论 -
java高并发系列 - 第15天:JUC中的Semaphore(信号量)
这个方法会响应线程中断,主线程中对t2、t3发送中断信号之后, acquire()方法会触发 InterruptedException异常,t2、t3最终没有获取到许可,但是他们都执行了finally中的释放许可的操作,最后导致许可数量变为了2,导致许可数量增加了。代码中 newSemaphore(2)创建了许可数量为2的信号量,每个线程获取1个许可,同时允许两个线程获取许可,从输出中也可以看出,同时有两个线程可以获取许可,其他线程需要等待已获取许可的线程释放许可之后才能运行。处等待,导致程序无法结束。原创 2023-08-10 14:03:06 · 189 阅读 · 0 评论 -
java高并发系列 - 第16天:JUC中等待多线程完成的工具类CountDownLatch,必备技能
CountDownLatch称之为闭锁,它可以使一个或一批线程在闭锁上等待,等到其他线程执行完相应操作后,闭锁打开,这些等待的线程才可以继续执行。确切的说,闭锁在内部维护了一个倒计数器。通过该计数器的值来决定闭锁的状态,从而决定是否允许等待的线程继续执行。常用方法:public CountDownLatch(int count):构造方法,count表示计数器的值,不能小于0,否者会报异常。原创 2023-08-07 14:41:33 · 191 阅读 · 0 评论 -
java高并发系列 - 第17天:JUC中的循环栅栏CyclicBarrier的6种使用场景
CyclicBarrier通常称为循环屏障。它和CountDownLatch很相似,都可以使线程先等待然后再执行。不过CountDownLatch是使一批线程等待另一批线程执行完后再执行;而CyclicBarrier只是使等待的线程达到一定数目后再让它们继续执行。原创 2023-08-03 20:41:16 · 248 阅读 · 0 评论 -
java高并发系列 - 第18天:JAVA线程池
大家用jdbc操作过数据库应该知道,操作数据库需要和数据库建立连接,拿到连接之后才能操作数据库,用完之后销毁。数据库连接的创建和销毁其实是比较耗时的,真正和业务相关的操作耗时是比较短的。每个数据库操作之前都需要创建连接,为了提升系统性能,后来出现了数据库连接池,系统启动的时候,先创建很多连接放在池子里面,使用的时候,直接从连接池中获取一个,使用完毕之后返回到池子里面,继续给其他需要者使用,这其中就省去创建连接的时间,从而提升了系统整体的性能。原创 2023-08-02 17:02:22 · 199 阅读 · 0 评论 -
java高并发系列 - 第19天:JUC中的Executor框架详解1
Executors框架是Doug Lea的神作,通过这个框架,可以很容易的使用线程池高效地处理并行任务。原创 2023-08-02 15:17:09 · 140 阅读 · 0 评论 -
java高并发系列 - 第20天:JUC中的Executor框架详解2
ExecutorCompletionService内部有个阻塞队列,任意一个任务完成之后,会将任务的执行结果(Future类型)放入阻塞队列中,然后其他线程可以调用它take、poll方法从这个阻塞队列中获取一个已经完成的任务,获取任务返回结果的顺序和任务执行完成的先后顺序一致,所以最先完成的任务会先返回。从输出中可以看出和我们希望的结果一致,代码中下单顺序是:冰箱、洗衣机,冰箱送货耗时5秒,洗衣机送货耗时2秒,洗衣机先到的,然后被送上楼了,冰箱后到被送上楼,总共耗时12秒,和期望的方案一样。原创 2023-08-02 10:51:23 · 157 阅读 · 0 评论 -
java高并发系列 - 第21天:java中的CAS
否则,处理器不做任何操作。上面的update语句相当于我们说的CAS操作,执行这个update语句的时候,多线程情况下,数据库会对当前订单记录加锁,保证只有一条执行成功,执行成功的,影响行数为1,执行失败的影响行数为0,根据影响行数来决定提交还是回滚事务。对count++操作的时候,我们让多个线程排队处理,多个线程同时到达request()方法的时候,只能允许一个线程可以进去操作,其他的线程在外面候着,等里面的处理完毕出来之后,外面等着的再进去一个,这样操作count++就是排队进行的,结果一定是正确的。原创 2023-08-01 20:18:14 · 256 阅读 · 0 评论 -
java高并发系列 - 第22天:JUC底层工具类Unsafe
最近我们一直在学习java高并发,java高并发中主要涉及到类位于java.util.concurrent包中,简称juc,juc中大部分类都是依赖于Unsafe来实现的,主要用到了Unsafe中的CAS、线程挂起、线程恢复等相关功能。所以如果打算深入了解JUC原理的,必须先了解一下Unsafe类。先上一幅Unsafe类的功能图:原创 2023-08-01 17:11:03 · 345 阅读 · 0 评论 -
java高并发系列 - 第23天:JUC中原子类,一篇就够了
什么是原子操作?atomic 翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰,所以,所谓原子类说简单点就是具有原子操作特征的类,原子操作类提供了一些修改数据的方法,这些方法都是原子操作的,在多线程情况下可以确保被修改数据的正确性。原创 2023-08-01 16:15:56 · 306 阅读 · 0 评论 -
java高并发系列 - 第24天:ThreadLocal、InheritableThreadLocal(通俗易懂)
还是拿上面的问题,我们来分析一下,每个请求都是由一个线程处理的,线程就相当于一个人一样,每个请求相当于一个任务,任务来了,人来处理,处理完毕之后,再处理下一个请求任务。父线程相当于主管,子线程相当于干活的小弟,主管让小弟们干活的时候,将自己兜里面的东西复制一份给小弟们使用,主管兜里面可能有很多牛逼的工具,为了提升小弟们的工作效率,给小弟们都复制一个,丢到小弟们的兜里,然后小弟就可以从自己的兜里拿去这些东西使用了,也可以清空自己兜里面的东西。看一下上面的输出,有些traceId为null,这是为什么呢?原创 2023-08-01 11:47:12 · 154 阅读 · 0 评论 -
java高并发系列 - 第25天:掌握JUC中的阻塞队列
重点需要了解BlockingQueue中的所有方法,以及他们的区别重点掌握ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、DelayQueue的使用场景需要处理的任务有优先级的,使用PriorityBlockingQueue处理的任务需要延时处理的,使用DelayQueue。原创 2023-07-31 15:15:56 · 236 阅读 · 0 评论 -
java高并发系列 - 第26篇:学会使用JUC中常见的集合,常看看!
可以看一下这个类的名称:CopyOnWrite,意思是在写入操作的时候,进行一次自我复制,换句话说,当这个List需要修改时,并不修改原有内容(这对于保证当前在读线程的数据一致性非常重要),而是在原有存放数据的数组上产生一个副本,在副本上修改数据,修改完毕之后,用副本替换原来的数组,这样也保证了写操作不会影响读。3种操作,每种操作有2个方法,不同点是队列为空或者满载时,调用方法是抛出异常还是返回特殊值,大家按照表格中的多看几遍,加深记忆。实现了Deque接口,内部使用链表实现的高效的并发双端队列。原创 2023-07-24 14:18:05 · 91 阅读 · 0 评论 -
java高并发系列 - 第27天:实战篇,接口性能提升几倍原来这么简单
对于无依赖的操作尽量采用并行方式去执行,可以很好的提升接口的性能。原创 2023-07-24 13:46:11 · 115 阅读 · 0 评论 -
java并发系列 - 第28天:实战篇,微服务日志的伤痛,一并帮你解决掉
关于上面几点,我们需要做的:日志发送的地方进行改造,引入消息中间件,将日志异步发送到消息中间件中,查询的地方采用elasticsearch,日志系统需要订阅消息中间件中的日志,然后丢给elasticsearch建索引,方便快速检索,咱们来一点点的介绍。多个服务之间日志追踪的问题:当一个请求过来的时候,在入口处生成一个trace_id,然后放在ThreadLocal中,如果内部设计到多个服务之间相互调用,调用其他服务的时,将trace_id顺便携带过去。本文主要讨论通过日志来快速定位并解决问题。原创 2023-07-24 11:32:53 · 115 阅读 · 0 评论 -
java并发系列 - 第29天:高并发中常见的限流方式
从原理上看,令牌桶算法和漏桶算法是相反的,一个“进水”,一个是“漏水”。并发控制的,通俗解释:一大波人去商场购物,必须经过一个门口,门口有个门卫,兜里面有指定数量的门禁卡,来的人先去门卫那边拿取门禁卡,拿到卡的人才可以刷卡进入商场,拿不到的可以继续等待。以秒杀业务为例,10个iphone,100万人抢购,100万人同时发起请求,最终能够抢到的人也就是前面几个人,后面的基本上都没有希望了,那么我们可以通过控制并发数来实现,比如并发数控制在10个,其他超过并发数的请求全部拒绝,提示:秒杀失败,请稍后重试。原创 2023-07-24 09:58:21 · 175 阅读 · 0 评论 -
java并发系列 - 第30天:JUC中工具类CompletableFuture,必备技能
以下所有的方法都类同。CompletableFuture是java8中新增的一个类,算是对Future的一种增强,用起来很方便,也是会经常用到的一个工具类,熟悉一下。两个CompletionStage,谁执行返回的结果快,我就用那个CompletionStage的结果进行下一步的转化操作。两个CompletionStage,谁执行返回的结果快,我就用那个CompletionStage的结果进行下一步的消耗操作。从示例代码中可以看出,该方法只是消费执行完成的任务,并可以根据上面的任务返回的结果进行处理。原创 2023-07-21 10:29:54 · 139 阅读 · 0 评论 -
java高并发系列 - 第31天:获取线程执行结果,这6种方法你都知道?
代码中使用FutureTask实现的,FutureTask实现了Runnable接口,并且内部带返回值,所以可以传递给Thread直接运行,futureTask.get()会阻塞当前线程,直到FutureTask构造方法传递的任务执行完毕,get方法才会返回。此行结论有误,请跳过:join的方式,只能阻塞一个线程,如果其他线程中也需要获取thread线程的执行结果,join方法无能为力了。代码中通过join方式阻塞了当前主线程,当thread线程执行完毕之后,join方法才会继续执行。环境:jdk1.8。原创 2023-07-20 16:09:51 · 209 阅读 · 0 评论 -
8 个线程池最佳实践和坑!使用不当直接生产事故!!
从下图可以看出, ThreadPoolExecutor提供了获取线程池当前的线程数和活跃线程数、已经执行完成的任务数、正在排队中的任务数等等。线程数更严谨的计算的方法应该是:最佳线程数 = N(CPU 核心数)∗(1+WT(线程等待时间)/ST(线程计算时间)),其中 WT(线程等待时间)=线程运行总时间 - ST(线程计算时间)。一般建议是不同的业务使用不同的线程池,配置线程池的时候根据当前业务的情况对当前线程池进行配置,因为不同的业务的并发以及对资源的使用情况都不同,重心优化系统性能瓶颈相关的业务。转载 2023-07-17 17:32:21 · 193 阅读 · 0 评论 -
java高并发系列 - 第32天:高并发中计数器的实现方式有哪些?
LongAdder在并发量比较大的情况下,操作数据的时候,相当于把这个数字分成了很多份数字,然后交给多个人去管控,每个管控者负责保证部分数字在多线程情况下操作的正确性。先介绍一下LongAdder,说到LongAdder,不得不提的就是AtomicLong,AtomicLong是JDK1.5开始出现的,里面主要使用了一个long类型的value作为成员变量,然后使用循环的CAS操作去操作value的值,并发量比较大的情况下,CAS操作失败的概率较高,内部失败了会重试,导致耗时可能会增加。原创 2023-07-17 14:45:08 · 435 阅读 · 0 评论 -
java高并发系列 - 第34篇:google提供的一些好用的并发工具类
ListeningExecutorService接口继承于juc中的ExecutorService接口,对ExecutorService做了一些扩展,看其名字中带有Listening,说明这个接口自带监听的功能,可以监听异步执行任务的结果。上面通过调用Futures的静态方法addCallback在异步执行的任务中添加回调,回调的对象是一个FutureCallback,此对象有2个方法,任务执行成功调用onSuccess,执行失败调用onFailure。本文演示几个简单的案例,见一下guava的效果。原创 2023-07-14 14:08:14 · 221 阅读 · 0 评论 -
java高并发系列 - 第33篇:怎么演示公平锁和非公平锁?
公平锁和非公平锁体现在别人释放锁的一瞬间,如果前面已经有排队的,新来的是否可以插队,如果可以插队表示是非公平的,如果不可用插队,只能排在最后面,是公平的方式。示例。原创 2023-07-13 15:36:44 · 143 阅读 · 0 评论 -
线程池的一个BUG导致CPU达到100%
就是 1731 年,雍正九年,那个时候的皇帝还是九子夺嫡中一顿乱杀,冲出重围的胤禛大佬。在研究前面提到的编号为 8065320 的 BUG 的时候,我还发现一个意外收获,编号为 8051859 的 BUG,它们是挨着的,排排坐。他说,在这个示例下,如果你在一个只有单核的服务器上跑,然后使用 TOP 命令,会看到持续 60 秒的 CPU 使用率为 100%。因为 keepAlive 参数设置的为 0,那么就会导致线程在 getTask 方法里面非常频繁的循环,从而导致 CPU 飙高。原创 2023-07-13 14:35:03 · 1004 阅读 · 0 评论 -
多线程事务怎么回滚
多线程事务回滚原创 2023-03-10 16:51:31 · 317 阅读 · 0 评论 -
实现Spring Boot 异步线程间数据传递的四种方式
实现SpringBoot异步线程间数据传递的四种方式原创 2023-03-10 15:32:06 · 1053 阅读 · 3 评论 -
实现异步的8种方案
线程转载 2023-03-07 14:12:25 · 626 阅读 · 0 评论 -
代码改成多线程,出现的问题及分析
代码改成多线程,出现的问题及分析转载 2022-11-01 18:23:18 · 341 阅读 · 0 评论 -
分布式锁工具--Redisson
最强分布式锁工具:Redisson原创 2022-11-01 15:23:57 · 531 阅读 · 0 评论 -
ExecutorCompletionService结果没调用take,poll方法导致的生产事故
ExecutorCompletionService结果没调用take,poll方法导致的生产事故转载 2022-09-29 11:11:25 · 552 阅读 · 0 评论 -
CompletionService
CompletionService转载 2022-09-28 17:37:00 · 152 阅读 · 0 评论 -
「并发编程」多线程先执行完的先取结果:CompletionService
「并发编程」多线程先执行完的先取结果:CompletionService转载 2022-09-28 16:53:34 · 251 阅读 · 0 评论 -
CompletionService--线程返回值执行顺序
CompletionService--线程返回值执行顺序转载 2022-09-28 16:45:42 · 364 阅读 · 0 评论 -
Springboot多线程@Async和CompletableFuture实现异步
Springboot多线程@Async和CompletableFuture实现异步1、自定义配置线程池/** * TaskPoolConfig * * Description: * @author xiangwang17 * @date 2021/7/12 15:58 */@Configuration@ComponentScan("com.renai.lovepd.web.system.service")@EnableAsync@Slf4jpublic class Task原创 2021-08-06 12:19:58 · 653 阅读 · 0 评论