
Java并发
文章平均质量分 71
zhangzeyuaaa
这个作者很懒,什么都没留下…
展开
-
Java并发之流水线模式以及CompletableFuture实战
流水线模式是一种高效的并发处理模型,适用于需要分阶段处理的任务场景。通过合理设计线程池规模和使用等工具,可以显著提升代码的可读性和性能。避免回调地狱:通过链式调用或简化代码。合理配置线程池:根据任务类型选择合适的线程数和队列策略。异常处理:确保每个阶段的异常能够被捕获和处理。任务解耦:通过模块化设计提高系统的可维护性。通过以上优化,流水线模式可以成为Java并发编程中的强大工具,帮助开发者构建高效、可靠的并发系统。原创 2025-05-09 11:45:57 · 639 阅读 · 0 评论 -
Java 显式锁与 Condition 的使用详解
Java 中的 ReentrantLock 和 Condition 提供了比 synchronized 更灵活的线程同步机制。ReentrantLock 支持可重入锁、超时等待和公平锁,而 Condition 则用于线程的等待和唤醒,替代了传统的 Object.wait() 和 Object.notify()。通过生产者-消费者模型的示例,展示了如何使用 ReentrantLock 和 Condition 实现线程协作。常见误区包括不加锁调用 Condition.await(),这会导致 IllegalMo原创 2025-05-08 20:56:15 · 960 阅读 · 0 评论 -
Java线程阻塞方法LockSupport.park()/Thread.sleep()/Object.wait()详解:原理、区别
适合底层同步工具开发,提供最灵活的线程控制。适合简单延时,但需注意锁的释放问题。是经典的线程通信工具,适合条件驱动的协作场景。也是基于wait实现)开发者需根据具体需求选择合适的方法,并结合 JVM 和操作系统特性,编写高效、健壮的并发程序。理解这些方法的底层机制,不仅能优化性能,还能避免常见的并发陷阱(如死锁、资源泄漏)。原创 2025-05-08 17:24:38 · 1013 阅读 · 0 评论 -
CAS、CAS自旋、CAS自旋锁、CLH锁与Java AQS:深入理解并发编程核心机制
CAS(Compare and Swap)是一种无锁(Lock-Free)的原子操作,用于在多线程环境下实现数据同步。CLH(Craig, Landin, Hagersten)锁是一种基于链表的队列锁,通过隐式队列管理线程,减少缓存一致性流量。基于CAS自旋实现的锁,线程在获取锁失败时不会阻塞,而是循环尝试。理解这些机制的原理与实现,是编写高效、健壮并发代码的关键。CAS自旋是指线程在CAS失败后循环重试,直到成功。)的核心框架,用于构建锁和同步器(如。AQS提供需子类实现的抽象方法(如。原创 2025-05-08 12:25:23 · 578 阅读 · 0 评论 -
Java捕获InterruptedException异常后,会自动清空中断状态
异常,然后输出捕获异常后的中断状态。由于 Java 会自动清除中断状态,所以输出的中断状态为。在上述代码中,子线程开始睡眠 5 秒,主线程睡眠 1 秒后中断子线程。异常时,线程的中断状态会被自动清除,这是 Java 处理线程中断的一种机制。,Java 会自动清除该线程的中断状态。异常一般是在一个线程处于等待(像。等方法)状态时被另一个线程调用。,此时线程可以重新响应中断。原创 2025-05-04 22:18:32 · 230 阅读 · 0 评论 -
Java 线程池的核心线程数已满,什么情况下会创建新的线程?
是创建新线程的必要条件。此时,线程池会突破核心线程数限制,创建新线程直至达到最大线程数,后续任务将。原创 2025-03-09 19:55:25 · 236 阅读 · 0 评论 -
Java线程池 execute方法和submit方法,异常处理有何不同?
execute方法execute方法是Executor接口定义的方法,在类中实现,用于提交一个Runnable任务到线程池执行。submit方法submit方法是接口定义的方法,有多个重载版本,可接受Runnable或Callable任务,并且会返回一个Future对象,用于获取任务的执行结果。execute方法提交的任务抛出异常时,异常会直接影响工作线程,需要在任务内部或通过线程的进行处理。submit方法提交的任务抛出异常时,异常会被封装在Future对象中,需要通过调用Future的get。原创 2025-03-09 13:10:23 · 335 阅读 · 0 评论 -
Java主线程能拿到子线程抛出的异常吗?
在Java中,主线程默认情况下不能直接拿到子线程抛出的异常。原创 2025-03-08 11:35:45 · 255 阅读 · 0 评论 -
奇淫巧技,异步编程 CompletableFuture 是真的优雅
任务 1 执行完了再执行任务 2,甚至任务 1 执行的结果,作为任务 2 的入参数等等强大功能,下面就来学学 CompletableFuture 的 API。与此同时,Future 无法解决多个异步任务相互依赖的场景,简单点说就是,主线程需要等待子线程任务执行完毕之后在进行执行,这个时候你可能想到了 「表示第一个任务执行完成后,执行第二个回调方法任务,会将该任务的执行结果,作为入参,传递到回调方法中,并且回调方法是有返回值的。在大量请求过来的时候,处理逻辑复杂的话,响应会很慢。转载 2025-02-06 15:32:19 · 51 阅读 · 0 评论 -
自旋锁和互斥锁的区别
(1)、互斥锁mutex:独占锁;开销大(2)、自旋锁spin lock:轻量级的锁,开销小;适用于短时间内对锁的使用。如果自旋锁已经被其他的执行单元保持,调用者就一直循环在那里判断该自旋锁是否被释放注意:对于spin lock,如果递归调用过深,会导致死锁。转载 2022-08-23 14:41:45 · 272 阅读 · 0 评论 -
Java中的自旋锁
思路:每当有线程获取锁的时候,就给该线程分配一个递增的id,我们称之为排队号,同时,锁对应一个服务号,每当有线程释放锁,服务号就会递增,此时如果服务号与某个线程排队号一致,那么该线程就获得锁,由于排队号是递增的,所以就保证了最先请求获取锁的线程可以最先获取到锁,就实现了公平性。可以想象成银行办理业务排队,排队的每一个顾客都代表一个需要请求锁的线程,而银行服务窗口表示锁,每当有窗口服务完成就把自己的服务号加一,此时在排队的所有顾客中,只有自己的排队号与服务号一致的才可以得到服务。转载 2022-08-23 14:16:57 · 1357 阅读 · 0 评论 -
多生产者、多消费者模式中,如何停止消费者?(Countdownlatch + Poison(毒丸))
多线程生产者、消费者模式中,如何停止消费者 ?多生产者情况下对“毒丸”策略的应用生产者、消费者模式是多线程中的经典问题。通过中间的缓冲队列,使得生产者和消费者的速度可以相互调节。发散:一个主线程控制多个子线程,多个主线程控制多个子线程(countDownLunch使用理解)对于比较常见的单生产者、多消费者的情况,主要有以下两种策略:通过volatile boolean producerDone =false 来标示是否完成。生产者结束后标示为true, 消费者轮询这个变量来决定自己是否退出。转载 2022-04-12 10:21:52 · 766 阅读 · 0 评论 -
使用sleep避免java死循环导致的CPU占用率过高
sleep(long millis) 线程睡眠 millis 毫秒使用sleep方法可以避免cpu空转,防止cpu占用率过高。public static void main(String[] args) { while (true) { // you code... try { Thread.sleep(3); } catch (InterruptedException e) { e.printS原创 2021-11-02 11:40:31 · 1790 阅读 · 0 评论 -
Coroutine(协程) in Java - Quasar Fiber实现
简介说到协程(Coroutine),很多人会想到go,lua,erlang等语言,其实JVM上也有蛮多的实现,如PicoThread,Kilim,Quasar等,本文主要介绍其中一种Coroutine实现 -- Quasar Fiber,Quasar Fiber相对来说流行度更好一些,如果之前没有接触过协程(用户级轻量级线程),可以看下What are fibers、Coroutine那么为什么要使用协程?协程可以用同步的编程方式达到或接近于纯异步的性能,而没有异步带来的Callback hell转载 2021-03-01 20:59:44 · 1955 阅读 · 0 评论 -
线程中断Thread.interrupt()的用法
package p;import java.math.BigInteger;public class ThreadInterruptTest { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { Thread t = n原创 2015-10-25 18:24:32 · 810 阅读 · 0 评论 -
多线程执行多类型任务(线程通信wait/notify(notifyAll)):生产者消费者模型(二)
每个任务有多个线程执行。工作台类原创 2014-10-22 17:28:03 · 1052 阅读 · 0 评论 -
经典的生产者消费者模型(一)
package com.zzj.concurrency;import java.util.LinkedList;public class ProducerConsumerModel { private final LinkedList queue = new LinkedList<>(); private final int max = 3; public synchroni原创 2017-10-25 23:47:53 · 433 阅读 · 0 评论 -
经典的生产者消费者模型(二)
package com.zzj.concurrency;import java.util.LinkedList;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public原创 2017-10-26 20:51:56 · 345 阅读 · 0 评论 -
ForkJoin框架示例(一)
package com.zzj.concurrency;import java.io.IOException;import java.util.Random;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.RecursiveAction;/** * 计算一千万个1到100之间的数值之和,此示例使用没有返原创 2017-10-26 21:35:26 · 708 阅读 · 0 评论 -
ForkJoin框架示例(二)
package com.zzj.concurrency;import java.io.IOException;import java.util.Random;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.RecursiveTask;/** * 计算一千万个1到100之间的数值之和 * @author原创 2017-10-26 21:36:55 · 432 阅读 · 0 评论 -
多线程执行多类型任务(线程通信wait/notify(notifyAll)):生产者消费者模型(一)
这里使用自增和自减来模拟生产者消费者模型。原创 2014-10-22 10:26:49 · 1032 阅读 · 0 评论 -
Java多线程执行单一类型任务:卖车票模型
车票类:package com.xs.thread;public class Ticket { private int t; public Ticket(int t) { this.t = t; } public synchronized int getTicket() throws NoTicketsException { if (t < 1) { throw ne原创 2014-10-22 10:03:16 · 1084 阅读 · 0 评论 -
Java并发总览
原创 2017-09-14 14:37:06 · 384 阅读 · 0 评论 -
同步、异步、阻塞和非阻塞
正常情况下,我们的程序以同步非阻塞的方式在运行。但是我们的程序总会出现一些耗时操作,比如复杂的计算(找出1到10亿之间的素数)和程序本身无法控制的操作(IO操作、网络请求)。包含这些耗时操作的方法我们可以把它称为阻塞方法,包含这些耗时操作的任务我们可以把它称为阻塞任务。阻塞与非阻塞是以是否耗时来定义的。如果程序中存在大量阻塞操作,就会影响程序性能。但是阻塞的存在是客观事实,我们的程序是无法改变原创 2015-12-12 17:04:37 · 923 阅读 · 0 评论 -
什么情况下使用多线程?
用并发解决的问题大体上可以分为“速度”和“设计可管理性”两种。速度问题听起来很简单:如果你想要一个程序运行得更快,那么可以将其断开为多个片段,在单独的处理器上运行每个片段。并发是用于多处理器编程的基本工具。当前,摩尔定律已经有些过时了(至少对于传统芯片是这样),速度提高是以多核处理器的形式而不是更快的芯片的形式出现的。为了使程序运行得更快,你必须学习如何利用这些额外的处理器,而这正是并发赋予你原创 2015-12-03 13:59:32 · 7469 阅读 · 0 评论 -
使用信号量Semaphore设置容器边界
class BoundedHashSet{ private final Set set; private final Semaphore semaphore; public BoundedHashSet(int bound) { set = Collections.synchronizedSet(new HashSet()); semaphore = new Semaphore(原创 2015-10-15 15:01:35 · 1054 阅读 · 0 评论 -
Java并发之CyclicBarrier示例
通过三个示例说明CyclicBarrier的使用。示例一赛跑时,等待所有人都准备好时才起跑:package com.xs.concurrent;import java.util.Random;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;p原创 2015-10-15 17:14:16 · 1171 阅读 · 1 评论 -
Java线程之CompletionService
当我们提交了批量任务,并且需要获取其结果时,可以使用以下方式:package com.zzj.concurrent.batchtask;import java.util.ArrayList;import java.util.List;import java.util.concurrent.ExecutionException;import java.util.concurrent.Exe原创 2015-10-29 10:27:53 · 649 阅读 · 0 评论 -
Java并发之ThreadPoolExecutor和FutureTask
ExecutorService.submit(Runnable task)方法及其重载方法的返回类型为Future,其真实类型为FutureTask。类图如下:future.get()是一个阻塞方法,知道任务完成才返回。再看ThreadPoolExecutor类图:当ExecutorService.submit(Runnable task)方法及其重载方法执行时(这些方法由原创 2015-10-14 16:31:00 · 4916 阅读 · 0 评论 -
Java同步容器和并发容器
同步容器Java常用的容器有ArrayList、LinkedList、HashMap等等,这些容器都是非线程安全的。如果有多个线程并发地访问这些容器时,就会出现问题。因此,在编写程序时,必须要求程序员手动地在任何访问到这些容器的地方进行同步处理,这样导致在使用这些容器的时候非常地不方便。所以,Java提供了同步容器供用户使用。在Java中,同步容器主要包括2类:1)Vect原创 2015-10-13 10:46:23 · 3721 阅读 · 4 评论 -
线程重用——线程池的基本原理
为简单起见,线程池中只有一个线程:package com.xs.concurrent;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;public class ThreadPool { private final BlockingQueue block原创 2015-10-19 11:32:34 · 5382 阅读 · 1 评论 -
对InterruptedException的正确处理
当在代码中调用了一个抛出InterruptedException异常的方法时,必须要处理对中断的响应。有两种基本的选择:1.传递InterruptedException。避开这个异常通常是最明智的策略——只需把InterruptedException传递给方法调用者。传递InterruptedException的方法包括,根本不捕获该异常,或者捕获该异常,然后在执行某种简单的清理工作后再次抛出原创 2015-11-30 12:49:02 · 10730 阅读 · 1 评论 -
volatile是否能保证数组中元素的可见性?
在javaeye有位朋友问了我一个非常好的问题。问题一个线程向volatile的数组中设置值,而另一个线程向volatile的数组中读取。比如seg.setValue(2),随后另一个线程调用seg.getValue(2),前一个线程设置的值对读取的线程是可见的吗?我看书上说volatile的数组只针对数组的引用具有volatile的语义,而不是它的元素。Concu转载 2016-12-10 22:16:00 · 2429 阅读 · 0 评论 -
AbstractQueuedSynchronizer的介绍和原理分析
如果我们去读concurrent包的源码时,会发现其真正的核心是 AbstractQueuedSynchronizer , 简称 AQS 框架 , 而 Doug Lea 大神正是此包的作者。简介提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架。该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础。使用的方法是继承,子类通过转载 2017-04-29 14:38:28 · 1103 阅读 · 0 评论 -
JAVA并发编程J.U.C学习总结
阅读目录前言 JSR 166及J.U.CExecutor框架(线程池、 Callable 、Future)AbstractQueuedSynchronizer (AQS框架)Locks & Condition(锁和条件变量)Synchronizers(同步器)Atomic Variables(原子变量)BlockingQueue(阻塞队列)Concurrent Collections(并转载 2017-04-29 14:25:45 · 1862 阅读 · 0 评论 -
CountDownLatch倒计数锁存器(Latch:门闩[shuan])
CountDownLatch 是一个通用同步工具,它有很多用途。将计数 1 初始化的 CountDownLatch 用作一个简单的开/关锁存器,或入口:在通过调用 countDown() 的线程打开入口前,所有调用 await 的线程都一直在入口处等待。用 N 初始化的 CountDownLatch 可以使一个线程在 N 个线程完成某项操作之前一直等待,或者使其在某项操作完成 N 次之前一原创 2015-10-14 11:41:01 · 1212 阅读 · 0 评论 -
关于Thread对象的suspend,resume,stop方法(已过时)
一、作用 对于老式得磁带录音机,上面都会有,暂停,继续,停止。Thread中suspend,resume,stop方法就类似。 suspend,使线程暂停,但是不会释放类似锁这样的资源。 resume,使线程恢复,如果之前没有使用suspend暂停线程,则不起作用。 stop,停止当前线程。不会保证释放当前线程占有的资源。转载 2016-12-18 00:50:38 · 14371 阅读 · 1 评论 -
Java thread.join()
thread.join()是让当前线程block住,等thread执行完之后,再继续执行 。比如有3个线程在执行计算任务,必须等三个线程都执行完才能汇总,那么这时候在主线程里面让三个线程join,最后计算结果既可。代码显示如下:原创 2015-03-04 09:44:05 · 1038 阅读 · 0 评论 -
java notify和notifyAll的区别
首先从名字可以了解,notify是通知一个线程获取锁,notifyAll是通知所有相关的线程去竞争锁。notify不能保证获得锁的线程,真正需要锁,并且可能产生死锁。举例1:所有人(消费者线程)准备吃饭,食堂没有开放(没有释放锁)打饭窗口(锁),所有人等待(WAITING)。食堂开饭打饭窗口(释放锁),并广播消息“开饭了”(notifyAll),所有人竞争排队,并等转载 2016-12-18 00:27:49 · 1063 阅读 · 0 评论 -
Java Thread.sleep()、Thread.yield()
1) sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。2) sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。3)它们都是Thread原创 2015-01-10 21:02:54 · 620 阅读 · 0 评论