
Java并发
文章平均质量分 95
Reset‘
这个作者很懒,什么都没留下…
展开
-
Java并发(十八)美团的线程池实际应用场景
面对业务中使用线程池遇到的实际问题,我们曾回到支持并发性问题本身来思考有没有取代线程池的方案,也曾尝试着去追求线程池参数设置的合理性,但面对业界方案具体落地的复杂性、可维护性以及真实运行环境的不确定性,我们在前两个方向上可谓“举步维艰”。最终,我们回到线程池参数动态化方向上探索,得出一个且可以解决业务问题的方案,虽然本质上还是没有逃离使用线程池的范畴,但是在成本和收益之间,算是取得了一个很好的平衡。原创 2024-07-31 17:57:49 · 394 阅读 · 0 评论 -
Java并发(十七)Java线程池的最佳实践(实际业务场景)
*CPU 密集型任务:**这种任务消耗的主要是 CPU 资源,可以将线程数设置为 N(CPU 核心数)+1,比 CPU 核心数多出来的一个线程是为了防止线程偶发的缺页中断,或者其它原因导致的任务暂停而带来的影响。综合来看,我们可以根据自己的业务场景,从“N+1”和“2N”两个公式中选出一个适合的,计算出一个大概的线程数量,之后通过实际压测,逐渐往“增大线程数量”和“减小线程数量”这两个方向调整,然后观察整体的处理时间变化,最终确定一个具体的线程数量。通过测试结果,我们可以看到每个线程所花费的时间。原创 2024-07-31 17:57:05 · 1121 阅读 · 0 评论 -
Java并发(十六)一文搞懂Java 线程池原理
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。Executor- 运行任务的简单接口。- 扩展了Executor接口。扩展能力:支持有返回值的线程;支持管理线程的生命周期。- 扩展了接口。扩展能力:支持定期执行任务。接口的默认实现。- Executor 框架最核心的类,它继承了类。接口的实现,一个可定时调度任务的线程池。Executors- 可以通过调用Executors的静态工厂方法来创建线程池并返回一个对象。原创 2024-07-31 17:55:41 · 1189 阅读 · 0 评论 -
Java并发(十五)Java并发工具类
和都能够实现线程之间的等待,只不过它们侧重点不同:一般用于某个线程 A 等待若干个其他线程执行完任务之后,它才执行;一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;另外,是不可以重用的,而是可以重用的。Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限。原创 2024-07-30 21:20:37 · 442 阅读 · 0 评论 -
Java并发(十四)Java原子类
保证线程安全是 Java 并发编程必须要解决的重要问题。Java 从原子性、可见性、有序性这三大特性入手,确保多线程的数据一致性。确保线程安全最常见的做法是利用锁机制(Lock)来对共享数据做互斥同步,这样在同一个时刻,只有一个线程可以执行某个方法或者某个代码块,那么操作必然是原子性的,线程安全的。互斥同步最主要的问题是线程阻塞和唤醒所带来的性能问题。volatile是轻量级的锁(自然比普通锁性能要好),它保证了共享变量在多线程中的可见性,但无法保证原子性。所以,它只能在一些特定场景下使用。原创 2024-07-30 21:20:01 · 430 阅读 · 0 评论 -
Java并发(十一)一文搞懂Java并发各种容器
同步容器将所有对容器状态的访问都串行化,以保证线程安全性,这种策略会严重降低并发性。Java 1.5 后提供了多种并发容器,使用并发容器来替代同步容器,可以极大地提高伸缩性并降低风险。并发容器对应的普通容器描述HashMapJava 1.8 之前采用分段锁机制细化锁粒度,降低阻塞,从而提高并发性;Java 1.8 之后基于 CAS 实现。SortedMap基于跳表实现的ArrayListSet基于实现。SortedSet基于实现。Queue线程安全的无界队列。底层采用单链表。支持 FIFO。原创 2024-07-29 15:06:33 · 1087 阅读 · 0 评论 -
Java并发(十三)Java并发工具类
注意,上面的代码,更侧重的是演示 Semaphore 的功能以及局限性,其实有很多线程编程中的反实践,比如使用了 sleep 来协调任务执行,而且使用轮询调用 availalePermits 来检测信号量获取情况,这都是很低效并且脆弱的,通常只是用在测试或者诊断场景。但是,从具体节奏来看,其实并不符合我们前面场景的需求,因为本例中 Semaphore 的用法实际是保证,一直有 5 个人可以试图乘车,如果有 1 个人出发了,立即就有排队的人获得许可,而这并不完全符合我们前面的要求。原创 2024-07-29 15:03:15 · 419 阅读 · 0 评论 -
Java并发(十二)AtomicInteger底层实现原理是什么?如何在自己的产品代码中应用CAS操作?
AtomicIntger 是对 int 类型的一个封装,提供原子性的访问和更新操作,其原子性操作的实现是基于 CAS()技术。所谓 CAS,表征的是一系列操作的集合,获取当前数值,进行一些运算,利用 CAS 指令试图进行更新。如果当前数值未变,代表没有其他线程进行并发修改,则成功更新。否则,可能出现不同的选择,要么进行重试,要么就返回一个成功或者失败的结果。从 AtomicInteger 的内部属性可以看出,它依赖于 Unsafe 提供的一些底层能力,进行底层操作;原创 2024-07-29 15:02:36 · 763 阅读 · 0 评论 -
Java并发(十)ForkJoin框架
对于简单的并行任务,你可以通过“线程池 +Future”的方案来解决;如果任务之间有聚合关系,无论是 AND 聚合还是 OR 聚合,都可以通过 CompletableFuture 来解决;而批量的并行任务,则可以通过 CompletionService 来解决。原创 2024-07-26 19:29:17 · 275 阅读 · 0 评论 -
Java并发(九)一文搞懂Java各种锁
确保线程安全最常见的做法是利用锁机制(Lock)来对共享数据做互斥同步,这样在同一个时刻,只有一个线程可以执行某个方法或者某个代码块,那么操作必然是原子性的,线程安全的。在工作、面试中,经常会听到各种五花八门的锁,听的人云里雾里。锁的概念术语很多,它们是针对不同的问题所提出的,通过简单的梳理,也不难理解。死锁是一种特定的程序状态,在实体之间,由于循环依赖导致彼此一直处于等待之中,没有任何个体可以继续前进。死锁不仅仅是在线程之间会发生,存在资源独占的进程之间同样也 可能出现死锁。原创 2024-07-26 12:33:34 · 850 阅读 · 0 评论 -
Java并发(八)ConcurrentHashMap 如何实现高效地线程安全
如何保证容器是线程安全的?ConcurrentHashMap 如何实现高效地线程安全?原创 2024-07-25 21:24:04 · 591 阅读 · 0 评论 -
Java并发(七)synchronized和ReentrantLock有什么区别?
synchronized 是 Java 内建的同步机制,所以也有人称其为 Intrinsic Locking,它提供了互斥的语义和可见性,当一个线程已经获取当前锁时,其他试图获取的线程只能等待或者阻塞在那里。在 Java 5 以前,synchronized 是仅有的同步手段,在代码中, synchronized 可以用来修饰方法,也可以使用在特定的代码块儿上,本质上 synchronized 方法等同于把方法全部语句用 synchronized 块包起来。原创 2024-07-24 15:40:22 · 1067 阅读 · 0 评论 -
Java并发(六)Java中的锁
Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自JDK 8和Netty 3.10.6)、使用场景进行举例,为读者介绍主流锁的知识点,以及不同的锁的适用场景。Java中往往是按照是否含有某一特性来定义锁,我们通过特性将锁进行分组归类,再使用对比的方式进行介绍,帮助大家更快捷的理解相关知识。本文Java中常用的锁以及常见的锁的概念进行了基本介绍,并从源码以及实际应用的角度进行了对比分析。原创 2024-07-24 15:39:33 · 1100 阅读 · 0 评论 -
Java并发(五)Java中的ThreadLocal详解
ThreadLocal是JDK1.2开始就提供的一个用来存储线程本地变量的类。ThreadLocal中的变量是在每个线程中独立存在的,当多个线程访问ThreadLocal中的变量的时候,其实都是访问的自己当前线程的内存中的变量,从而保证的变量的线程安全。我们一般在使用ThreadLocal的时候都是为了解决线程中存在的变量竞争问题。其实解决这类问题,通常大家也会想到使用synchronized来加锁解决。例如在解决SimpleDateFormat的线程安全的时候。原创 2024-07-23 12:40:32 · 642 阅读 · 0 评论 -
Java并发(四)Java线程基础
简言之,进程可视为一个正在运行的程序。它是系统运行程序的基本单位,因此进程是动态的。进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动。进程是操作系统进行资源分配的基本单位。线程是操作系统进行调度的基本单位。线程也叫轻量级进程(Light Weight Process),在一个进程里可以创建多个线程,这些线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量。原创 2024-07-23 12:38:32 · 1110 阅读 · 0 评论 -
Java并发(三)Java并发核心机制
Java 的包(简称 J.U.C)中提供了大量并发工具类,是 Java 并发能力的主要体现(注意,不是全部,有部分并发能力的支持在其他包中)。等。等。等。等。非阻塞队列 - 如:等。ExecutorExecutors等。我个人理解,Java 并发框架可以分为以下层次。由 Java 并发框架图不难看出,J.U.C 包中的工具类是基于volatileCAS这样的并发核心机制打造的。所以,要想深入理解 J.U.C 工具类的特性、为什么具有这样那样的特性,就必须先理解这些核心机制。原创 2024-07-22 17:59:07 · 1202 阅读 · 0 评论 -
Java并发(二)Java内存模型
此处的变量(Variables)与 Java 编程中所说的变量有所区别,它包括了实例字段、静态字段和构成数值对象的元素,但不包括局部变量与方法参数,因为后者是线程私有的,不会被共享,自然就不会存在竞争问题。不过实际开发中,Java 内存模型强烈建议虚拟机把 64 位数据的读写实现为具有原子性,目前各种平台下的商用虚拟机都选择把 64 位数据的读写操作作为原子操作来对待,因此我们在编写代码时一般不需要把用到的 long 和 double 变量专门声明为 volatile。但这么做,性能就堪忧了。原创 2024-07-22 17:58:05 · 786 阅读 · 0 评论 -
Java并发(一)CAS自旋锁
4、compareAndSet 方法,这就是实现 CAS 的核心方法了,在使用 AtomicBoolean 的这个方法时,只需要传递期望值和待更新的值即可,而它里面调用了 unsafe.compareAndSwapInt(this, valueOffset, e, u) 方法,它是个 native 方法,用 c++ 实现,具体的代码就不贴了,总之是利用了 CPU 的 cmpxchg 指令完成比较并替换,当然根据具体的系统版本不同,实现起来也有所区别,感兴趣的可以自行搜一下相关文章。否则,返回 false。原创 2024-07-22 17:57:18 · 1235 阅读 · 0 评论