Juc
文章平均质量分 90
阿昌喜欢吃黄桃
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
如果线程池中线程异常后:销毁还是复用?
本文探讨了Java线程池中线程异常后的处理机制。通过测试代码发现:使用execute()提交任务时,若线程抛出未捕获异常,线程会被移除并创建新线程;而使用submit()提交任务时,异常会被封装在Future中,需调用get()方法才能捕获,线程不会被移除。源码分析表明,execute()通过processWorkerExit()处理异常线程,而submit()通过FutureTask内部状态管理异常。两种方式均不影响线程池其他线程的正常执行。原创 2026-05-23 13:28:49 · 315 阅读 · 0 评论 -
并发线程工具类分享
本文分享了一个Java并发线程工具类ConcurrentExecutor,主要特点包括:支持信号量控制并发数、自定义线程池和简单易用。该工具类通过信号量机制限制并发线程数量,并提供阻塞等待所有线程执行完成的功能。使用示例展示了如何通过该工具类实现多线程调用AI模型,包括提交任务、阻塞等待和获取执行结果等操作。核心方法包括submit()提交任务、invokeAll()阻塞等待和getSyncExecuteResult()获取结果,适用于需要控制并发数的多线程场景。原创 2026-05-20 21:03:33 · 32 阅读 · 0 评论 -
Day864.CSP模型 -Java 并发编程实战
Actor 模型中 Actor 之间就是不能共享内存的,彼此之间通信只能依靠消息传递的方式。Golang 实现的 CSP 模型和 Actor 模型看上去非常相似,Golang 程序员中有句格言:“不要以共享内存方式通信,要以通信方式共享内存(Don’t communicate by sharing memory, share memory by communicating)。虽然 Golang 中协程之间,也能够以共享内存的方式通信,但是并不推荐;而推荐的以通信的方式共享内存,实际上指的就是。原创 2023-01-19 21:03:04 · 1986 阅读 · 0 评论 -
Day863.协程 -Java 并发编程实战
最近几年支持协程的开发语言越来越多了,Java OpenSDK 中 Loom 项目的目标就是支持协程,相信不久的将来,Java 程序员也可以使用协程来解决并发问题了。易用性。协程作为一项并发编程技术,本质上也不过是解决并发工具的易用性问题而已。对于易用性,最重要的就是要适应我们的思维模式,在工作的前几年,并没有怎么关注它,但是最近几年思维模式已成为重点关注的对象。因为思维模式对工作的很多方面都会产生影响,例如质量。一个软件产品是否能够活下去,从质量的角度看,最核心的就是代码写得好。原创 2023-01-18 22:03:40 · 1582 阅读 · 0 评论 -
Day862.STM软件事务内存 -Java 并发编程实战
STM 借鉴的是数据库的经验,数据库虽然复杂,但仅仅存储数据,而编程语言除了有共享变量之外,还会执行各种 I/O 操作,很显然 I/O 操作是很难支持回滚的。所以,STM 也不是万能的。目前支持 STM 的编程语言主要是函数式语言,函数式语言里的数据天生具备不可变性,利用这种不可变性实现 STM 相对来说更简单。另外,需要说明的是,文中的“实现 STM”部分参考了这篇博文以及一个GitHub项目,目前还很粗糙,并不是一个完备的 MVCC。如果对这方面感兴趣,可以参考。原创 2023-01-17 21:07:17 · 1247 阅读 · 0 评论 -
Day861.Actor模型 -Java 并发编程实战
处理能力,处理接收到的消息。存储能力,Actor 可以存储自己的内部状态,并且内部状态在不同 Actor 之间是绝对隔离的。通信能力,Actor 可以和其他 Actor 之间通信。创建更多的 Actor;发消息给其他 Actor;确定如何处理下一条消息。其中前两条还是很好理解的,就是最后一条,该如何去理解呢?前面说过 Actor 具备存储能力,它有自己的内部状态,所以你也可以把 Actor 看作一个状态机,把 Actor 处理消息看作是触发状态机的状态变化;原创 2023-01-16 22:24:22 · 843 阅读 · 0 评论 -
Day860.高性能数据库连接池HiKariCP -Java 并发编程实战
本质上,数据库连接池和线程池一样,都属于池化资源,作用都是避免重量级资源的频繁创建和销毁,对于数据库连接池来说,也就是避免数据库连接频繁创建和销毁。如下图所示,服务端会在运行期持有一定数量的数据库连接,当需要执行 SQL 时,并不是直接创建一个数据库连接,而是从连接池中获取一个;当 SQL 执行完,也并不是将数据库连接真的关掉,而是将其归还到连接池中。在实际工作中,都是使用各种持久化框架来完成数据库的增删改查,基本上不会直接和数据库连接池打交道,下面的示例代码并没有使用任何框架,而是。原创 2023-01-15 20:01:29 · 1268 阅读 · 0 评论 -
Day859.高性能队列Disruptor -Java 并发编程实战
一个是利用无锁算法避免锁的争用另外一个则是将硬件(CPU)的性能发挥到极致。尤其是后者,在 Java 领域基本上属于经典之作了。发挥硬件的能力一般是 C 这种面向硬件的语言常干的事儿,C 语言领域经常通过调整内存布局优化内存占用,而 Java 领域则用的很少,原因在于 Java 可以智能地优化内存布局,内存布局对 Java 程序员的透明的。这种智能的优化大部分场景是很友好的,但是如果想通过填充方式避免伪共享就必须绕过这种优化,关于这方面 Disruptor 提供了经典的实现,可以参考。原创 2023-01-14 20:46:13 · 826 阅读 · 0 评论 -
Day858.高性能网络应用框架Netty -Java 并发编程实战
Netty是一个款优秀的网络编程框架,性能非常好,为了实现高性能的目标,Netty 做了很多优化,例如优化了 ByteBuffer、支持零拷贝等等,和并发编程相关的就是它的线程模型了。Netty 的线程模型设计得很精巧,每个网络连接都关联到了一个线程上,这样做的好处是:对于一个网络连接,读写操作都是单线程执行的,从而避免了并发程序的各种问题。要想深入理解 Netty 的线程模型,还需要对网络相关知识有一定的理解,关于 Java IO 的演进过程,可以参考。原创 2023-01-13 20:36:32 · 820 阅读 · 0 评论 -
Day857.高性能限流器Guava RateLimiter -Java 并发编程实战
一个是令牌桶算法另一个是漏桶算法令牌桶算法是定时向令牌桶发送令牌,请求能够从令牌桶中拿到令牌,然后才能通过限流器;漏桶算法里,请求就像水一样注入漏桶,漏桶会按照一定的速率自动将水漏掉,只有漏桶里还能注入水的时候,请求才能通过限流器。令牌桶算法和漏桶算法很像一个硬币的正反面,所以你可以参考令牌桶算法的实现来实现漏桶算法。Guava是如何实现令牌桶算法的,示例代码是对的简化,Guava RateLimiter 扩展了标准的令牌桶算法,比如还能支持预热功能。原创 2023-01-12 20:29:14 · 996 阅读 · 1 评论 -
Day856.多线程设计模式一些列问题 -Java 并发编程实战
Hi,我是阿昌,今天学习记录的是关于的内容。是前人解决并发问题的经验总结,当试图解决一个并发问题时,首选方案往往是使用匹配的设计模式,这样能避免走弯路。同时,由于都熟悉设计模式,所以使用设计模式还能提升方案和代码的可理解性。原创 2023-01-11 21:13:00 · 985 阅读 · 0 评论 -
Day855.生产者-消费者模式 -Java 并发编程实战
Java 语言提供的线程池本身就是一种生产者 - 消费者模式的实现,但是线程池中的线程每次只能从任务队列中消费一个任务来执行,对于大部分并发场景这种策略都没有问题。但是有些场景还是需要自己来实现,例如需要批量执行以及分阶段提交的场景。生产者 - 消费者模式在分布式计算中的应用也非常广泛。在分布式场景下,你可以借助分布式消息队列(MQ)来实现生产者 - 消费者模式。MQ一种是点对点模型一种是发布订阅模型。原创 2023-01-10 21:50:01 · 825 阅读 · 1 评论 -
Day854.两阶段终止模式 -Java 并发编程实战
两阶段终止模式一个是仅检查终止标志位是不够的,因为线程的状态可能处于休眠态;另一个是仅检查线程的中断状态也是不够的,因为我们依赖的第三方类库很可能没有正确处理中断异常。当你使用 Java 的线程池来管理线程的时候,需要依赖线程池提供的 shutdown() 和 shutdownNow() 方法来终止线程池。不过在使用时需要注意它们的应用场景,尤其是在使用 shutdownNow() 的时候,一定要谨慎。原创 2023-01-09 22:01:05 · 521 阅读 · 0 评论 -
Day853.WorkerThread模式 -Java 并发编程实战
解决并发编程里的分工问题,最好的办法是和现实世界做对比。对比现实世界构建编程领域的模型,能够让模型更容易理解。Thread-Per-Message 模式,类似于现实世界里的委托他人办理,而今天介绍的 Worker Thread 模式则类似于车间里工人的工作模式。如果你在设计阶段,发现对业务模型建模之后,模型非常类似于车间的工作模式,那基本上就能确定可以在实现阶段采用 Worker Thread 模式来实现。Worker Thread 模式和 Thread-Per-Message 模式的区别有哪些呢?原创 2023-01-08 17:17:14 · 649 阅读 · 0 评论 -
Day852.Thread-Per-Message模式 -Java 并发编程实战
并发编程领域的分工问题,指的是如何高效地拆解任务并分配给线程。并发工具类模块,例如 Future、CompletableFuture 、CompletionService、Fork/Join 计算框架等,这些工具类都能很好地解决特定应用场景的问题,所以,这些工具类曾经是 Java 语言引以为傲的。不过这些工具类都继承了 Java 语言的老毛病:太复杂。如果一直从事 Java 开发,估计你已经习以为常了,习惯性地认为这个复杂度是正常的。原创 2023-01-07 20:04:54 · 545 阅读 · 0 评论 -
Day851.Balking模式 -Java 并发编程实战
Balking 模式和 Guarded Suspension 模式从实现上看似乎没有多大的关系,Balking 模式只需要用互斥锁就能解决,而 Guarded Suspension 模式则要用到管程这种高级的并发原语;但是从应用的角度来看,它们解决的都是“线程安全的 if”语义,不同之处在于,Guarded Suspension 模式会等待 if 条件为真,而 Balking 模式不会等待。原创 2023-01-06 22:21:08 · 973 阅读 · 0 评论 -
Day850.GuardedSuspension模式 -Java 并发编程实战
模式本质上是一种等待唤醒机制的实现,只不过 Guarded Suspension 模式将其规范化了。规范化的好处是你无需重头思考如何实现,也无需担心实现程序的可理解性问题,同时也能避免一不小心写出个 Bug 来。原创 2023-01-05 21:55:59 · 888 阅读 · 0 评论 -
Day849.ThreadLocal线程本地存储模式 -Java 并发编程实战
线程本地存储模式本质上是一种避免共享的方案,由于没有共享,所以自然也就没有并发问题。如果你需要在并发场景中使用一个线程不安全的工具类,最简单的方案就是避免共享。避免共享一种方案是将这个工具类作为局部变量使用,另外一种方案就是线程本地存储模式。这两种方案,局部变量方案的缺点是在高并发场景下会频繁创建对象,而线程本地存储方案,每个线程只需要创建一个工具类的实例,所以不存在频繁创建对象的问题。。原创 2023-01-04 21:37:38 · 490 阅读 · 0 评论 -
Day848.Copy-on-Write模式 -Java 并发编程实战
目前在 Java 并发编程领域知名度不是很高,很多人都在无意中把它忽视了,但其实 Copy-on-Write 才是最简单的并发解决方案。它是如此简单,以至于 Java 中的基本数据类型 String、Integer、Long 等都是基于 Copy-on-Write 方案实现的。Copy-on-Write 是一项非常通用的技术方案,在很多领域都有着广泛的应用。不过,它也有缺点的,那就是消耗内存。原创 2023-01-03 20:41:00 · 736 阅读 · 0 评论 -
Day847.Immutability模式 -Java 并发编程实战
利用Immutability 模式解决并发问题,也许你觉得有点陌生,其实天天都在享受它的战果。Java 语言里面的 String 和 Long、Integer、Double 等基础类型的包装类都具备不可变性,这些对象的线程安全性都是靠不可变性来保证的。Immutability 模式是最简单的解决并发问题的方法,建议当你试图解决一个并发问题时,可以首先尝试一下 Immutability 模式,看是否能够快速解决。具备不变性的对象,只有一种状态,这个状态由对象内部所有的不变属性共同决定。原创 2023-01-02 15:00:15 · 826 阅读 · 0 评论 -
Day846.并发工具类一些问题 -Java 并发编程实战
Hi,我是阿昌,今天学习记录的是关于并发工具类一些问题的内容。关于Java SDK 提供的并发工具类(JUC),这些工具类都是久经考验的,所以学好用好它们对于解决并发问题非常重要。在介绍这些工具类的时候,重点介绍了这些工具类的产生背景、应用场景以及实现原理,目的就是在面对并发问题的时候,有思路,有办法。只有思路、办法有了,才谈得上开始动手解决问题。。千里之堤毁于蚁穴,细节虽然不能保证成功,但是可以导致失败,所以一直都强调要关注细节。原创 2023-01-01 19:14:38 · 1136 阅读 · 0 评论 -
Day845.Fork/Join -Java 并发编程实战
Fork/Join并行计算框架主要解决的是分治任务。分治的核心思想是“分而治之”:将一个大的任务拆分成小的子任务去解决,然后再把子任务的结果聚合起来从而得到最终结果。这个过程非常类似于大数据处理中的 MapReduce,所以你可以把 Fork/Join 看作单机版的 MapReduce。Fork/Join 并行计算框架的核心组件是 ForkJoinPool。ForkJoinPool 支持任务窃取机制,能够让所有线程的工作量基本均衡,不会出现有的线程很忙,而有的线程很闲的状况,所以性能很好。原创 2022-12-31 21:36:08 · 1109 阅读 · 0 评论 -
Day844.CompletionService -Java 并发编程实战
当需要批量提交异步任务的时候建议你使用 CompletionService。CompletionService 将线程池 Executor 和阻塞队列 BlockingQueue 的功能融合在了一起,能够让批量异步任务的管理更简单。除此之外,CompletionService 能够让异步任务的执行结果有序化,先执行完的先进入阻塞队列,利用这个特性,可以轻松实现后续处理的有序性,避免无谓的等待,同时还可以快速实现诸如 Forking Cluster 这样的需求。原创 2022-12-30 22:01:25 · 605 阅读 · 0 评论 -
Day843.CompletableFuture -Java 并发编程实战
回调地狱应该说在前些年,异步编程还是声名狼藉的。不过最近几年,伴随着ReactiveX的发展(Java 语言的实现版本是 RxJava),回调地狱已经被完美解决了,异步编程已经慢慢开始成熟,Java 语言也开始官方支持异步编程:在 1.8 版本提供了 CompletableFuture,在 Java 9 版本则提供了更加完备的 Flow API,异步编程目前已经完全工业化。因此,学好异步编程还是很有必要的。原创 2022-12-29 21:00:20 · 595 阅读 · 0 评论 -
Day841.Executor与线程池-Java 并发编程实战
线程池在 Java 并发编程领域非常重要,很多大厂的编码规范都要求必须通过线程池来管理线程。线程池和普通的池化资源有很大不同,线程池实际上是生产者 - 消费者模式的一种实现,理解生产者 - 消费者模式是理解线程池的关键所在。使用线程池,默认情况下创建的线程名字都类似pool-1-thread-2这样,没有业务含义。而很多情况下为了便于诊断问题,都需要给线程赋予一个有意义的名字,那你知道有哪些办法可以给线程池里的线程指定名字吗?原创 2022-12-27 20:07:08 · 488 阅读 · 0 评论 -
Day840.原子类-Java 并发编程实战
无锁方案相对于互斥锁方案,优点非常多,首先性能好,其次是基本不会出现死锁问题(但可能出现饥饿和活锁问题,因为自旋会反复重试)。Java 提供的原子类大部分都实现了 compareAndSet() 方法,基于 compareAndSet() 方法,你可以构建自己的无锁数据结构,但是建议你不要这样做,这个工作最好还是让大师们去完成,原因是无锁算法没你想象的那么简单。原创 2022-12-26 21:24:28 · 389 阅读 · 0 评论 -
Day839.并发容器-Java 并发编程实战
Java 并发容器的内容很多,但鉴于篇幅有限,只是对一些关键点进行了梳理和介绍。在实际工作中,不单要清楚每种容器的特性,还要能选对容器,这才是关键,至于每种容器的用法,用的时候看一下 API 说明就可以了,这些容器的使用都不难。在文中,甚至都没有介绍 Java 容器的快速失败机制(Fail-Fast),原因就在于当你选对容器的时候,根本不会触发它。原创 2022-12-24 19:20:35 · 472 阅读 · 0 评论 -
Day838.CountDownLatch&CyclicBarrier-Java 并发编程实战
主要用来解决一个线程等待多个线程的场景,可以类比旅游团团长要等待所有的游客到齐才能去下一个景点;是一组线程之间互相等待,更像是几个驴友之间不离不弃。除此之外 CountDownLatch 的计数器是不能循环利用的,也就是说一旦计数器减到 0,再有线程调用 await(),该线程会直接通过。但 CyclicBarrier 的计数器是可以循环利用的,而且具备自动重置的功能,一旦计数器减到 0 会自动重置到你设置的初始值。除此之外,CyclicBarrier 还可以设置回调函数,可以说是功能丰富。原创 2022-12-23 15:59:23 · 510 阅读 · 0 评论 -
Day837.StampedLock-Java 并发编程实战
StampedLock 的使用看上去有点复杂,但是如果你能理解乐观锁背后的原理,使用起来还是比较流畅的。建议你认真揣摩 Java 的官方示例,这个示例基本上就是一个最佳实践。我们把 Java 官方示例精简后,形成下面的代码模板,建议你在实际工作中尽量按照这个模板来使用 StampedLock。StampedLock 读模板// 乐观读 long stamp = sl . tryOptimisticRead();// 读入方法局部变量 . . . . . . // 校验stamp if(!原创 2022-12-22 10:40:34 · 320 阅读 · 0 评论 -
Day836.ReadWriteLock -Java 并发编程实战
读写锁类似于 ReentrantLock,也支持公平模式和非公平模式。读锁和写锁都实现了 java.util.concurrent.locks.Lock 接口,所以除了支持 lock() 方法外,tryLock()、lockInterruptibly() 等方法也都是支持的。但是有一点需要注意,那就是只有写锁支持条件变量,读锁是不支持条件变量的,读锁调用 newCondition() 会抛出 UnsupportedOperationException 异常。原创 2022-12-20 21:31:27 · 380 阅读 · 0 评论 -
Day835.Semaphore -Java 并发编程实战
信号量在 Java 语言里面名气并不算大,但是在其他语言里却是很有知名度的。Java 在并发编程领域走的很快,重点支持的还是管程模型。管程模型理论上解决了信号量模型的一些不足,主要体现在易用性和工程化方面,例如用信号量解决曾经提到过的阻塞队列问题,就比管程模型麻烦很多。在上面对象池的例子中,对象保存在了 Vector 中,Vector 是 Java 提供的线程安全的容器,如果我们把 Vector 换成 ArrayList,是否可以呢?原创 2022-12-19 21:03:51 · 469 阅读 · 0 评论 -
Day834.Dubbo如何用管程实现异步转同步 -Java 并发编程实战
是管程的一种实现,所以能否用好 Lock 和 Condition 要看你对管程模型理解得怎么样。Lock&Condition 实现的管程相对于 synchronized 实现的管程来说更加灵活、功能也更丰富。了解原理比了解实现更能让你快速学好并发编程,所以没有介绍太多 Java SDK 并发包里锁和条件变量是如何实现的。但如果对实现感兴趣,可以参考《Java 并发编程的艺术》一书的第 5 章《Java 中的锁》,里面详细介绍了实现原理,写得非常好。另外,专栏里对。原创 2022-12-18 14:56:55 · 1074 阅读 · 0 评论 -
Day833.Lock和Condition(上):隐藏在并发包中的管程 -Java 并发编程实战
会发现创建的锁的具体类名是,这个翻译过来叫可重入锁,这个概念一直没有介绍过。所谓可重入锁,顾名思义,指的是线程可以重复获取同一把锁。例如下面代码中,当线程 T1 执行到 ① 处时,已经获取到了锁 rtl ,当在 ① 处调用 get() 方法时,会在 ② 再次对锁 rtl 执行加锁操作。此时,如果锁 rtl 是可重入的,那么线程 T1 可以再次加锁成功;如果锁 rtl 是不可重入的,那么线程 T1 此时会被阻塞。除了可重入锁,可能你还听说过可重入函数,可重入函数怎么理解呢?指的是线程可以重复调用?原创 2022-12-17 13:51:17 · 478 阅读 · 0 评论 -
Day832.用面向对象思想写好并发程序 -Java 并发编程实战
利用面向对象思想编写并发程序,一个关键点就是利用面向对象里的封装特性,由于篇幅原因,这里只做了简单介绍,详细的可以借助相关资料定向学习。而对共享变量进行封装,要避免“逸出”,所谓“逸出”简单讲就是共享变量逃逸到对象的外面,比如在《Happens-Before 规则》那一篇讲过构造函数里的 this“逸出”。这些都是必须要避免的。类 SafeWM 不满足库存下限要小于库存上限这个约束条件,那你来试试修改一下,让它能够在并发条件下满足库存下限要小于库存上限这个约束条件。原创 2022-12-16 23:11:12 · 914 阅读 · 0 评论 -
Day831.局部变量为什么是线程安全的 -Java 并发编程实战
调用栈是一个通用的计算机概念,所有的编程语言都会涉及到,Java 调用栈相关的知识,并没有花费很大的力气去深究,但是靠着那点 C 语言的知识,稍微思考一下,基本上也就推断出来了。递归调用太深,可能导致栈溢出。原因是什么?有哪些解决方案呢?栈溢出原因:因为每调用一个方法就会在栈上创建一个栈帧,方法调用结束后就会弹出该栈帧,而栈的大小不是无限的,所以递归调用次数过多的话就会导致栈溢出。而递归调用的特点是每递归一次,就要创建一个新的栈帧,而且还要保留之前的环境(栈帧),直到遇到结束条件。原创 2022-12-15 22:10:40 · 755 阅读 · 0 评论 -
Day830.创建多少线程才是合适的 -Java 并发编程实战
很多人都知道线程数不是越多越好,但是设置多少是合适的,却又拿不定主意。其实只要把握住一条原则就可以了,这条原则就是将硬件的性能发挥到极致。上面针对CPU 密集型和I/O 密集型计算场景都给出了理论上的最佳公式,这些公式背后的目标其实就是将硬件的性能发挥到极致。对于 I/O 密集型计算场景,I/O 耗时和 CPU 耗时的比值是一个关键参数,不幸的是这个参数是未知的,而且是动态变化的,所以工程上,要估算这个参数,然后做各种不同场景下的压测来验证我们的估计。原创 2022-12-14 22:40:02 · 505 阅读 · 0 评论 -
Day829.Java线程的生命周期 -Java 并发编程实战
理解 Java 线程的各种状态以及生命周期对于诊断多线程 Bug 非常有帮助,多线程程序很难调试,出了 Bug 基本上都是靠日志,靠线程 dump 来跟踪问题,分析线程 dump 的一个基本功就是分析线程状态,大部分的死锁、饥饿、活锁问题都需要跟踪分析线程的状态。可以通过 jstack 命令或者Java VisualVM这个可视化工具将 JVM 所有的线程栈信息导出来,完整的线程栈信息不仅包括线程的当前状态、调用栈,还包括了锁的信息。原创 2022-12-13 22:14:39 · 332 阅读 · 0 评论 -
Day828.多线程原语:管程 -Java 并发编程实战
不知道是否曾思考过这个问题:为什么 Java 在 1.5 之前仅仅提供了 synchronized 关键字及 wait()、notify()、notifyAll() 这三个看似从天而降的方法?在刚接触 Java 的时候,以为它会提供信号量这种编程原语,因为操作系统原理课程告诉我,用信号量能解决所有并发问题,结果发现不是。Java 采用的是管程技术,synchronized 关键字及 wait()、notify()、notifyAll() 这三个方法都是管程的组成部分。原创 2022-12-12 22:09:40 · 884 阅读 · 0 评论 -
Day827.安全性、活跃性以及性能问题 -Java 并发编程实战
并发编程是一个复杂的技术领域,微观上涉及到原子性问题、可见性问题和有序性问题,宏观则表现为安全性、活跃性以及性能问题。在设计并发程序的时候,主要是从宏观出发,也就是要重点关注它的安全性、活跃性以及性能。安全性方面要注意数据竞争和竞态条件,活跃性方面需要注意死锁、活锁、饥饿等问题,性能方面虽然介绍了两个方案,但是遇到具体问题,还是要具体分析,根据特定的场景选择合适的数据结构和算法。要解决问题,要把问题分析清楚。原创 2022-12-11 16:31:20 · 618 阅读 · 0 评论 -
Day826.Java多线程等待&通知机制 -Java 并发编程实战
等待 - 通知机制是一种非常普遍的线程间协作的方式。Java 语言内置的 synchronized 配合 wait()、notify()、notifyAll() 这三个方法可以快速实现这种机制,但是它们的使用看上去还是有点复杂,所以需要认真理解等待队列和 wait()、notify()、notifyAll() 的关系。最好用现实世界做个类比,这样有助于理解。很多面试都会问到,wait() 方法和 sleep() 方法都能让当前线程挂起一段时间,那它们的区别是什么?现在你也试着回答一下吧。wait与。原创 2022-12-10 19:16:31 · 329 阅读 · 0 评论
分享