
并发编程
文章平均质量分 91
Java并发编程
、楽.
放弃很容易,但坚持一定很酷!
展开
-
手撕并发编程:十分钟搞定Java内存模型
在本文中,我们对 Java 内存模型进行了全面的概述。Java 内存模型是 Java 虚拟机规范的一部分,为 Java 开发人员提供了一种抽象的内存模型,用于描述多线程环境下的内存访问行为。Java 内存模型关注并发编程中的原子性、可见性和有序性问题,并提供了一系列同步原语(如volatile等)来实现这些原则。此外,还定义关系,用于描述操作之间的偏序关系,从而确保内存访问的正确性和一致性。Java 内存模型的主要优势在于它为并发编程提供了基础,简化了复杂性。原创 2023-08-17 23:40:25 · 427 阅读 · 0 评论 -
并发基础之线程与锁重点梳理与总结
本文主要将线程与锁的重点进行梳理与总结,从而能对并发基础有一个更好的掌握。我们按照如下流程来进行一个大致的梳理。1. 并发?并行?首先我们来点老生常谈的话题,什么是并发?什么是并行?相信这个大家应该都很了解了。并发:在同一时间段上同时执行,比如在十毫米这个时间段内,前五毫秒做一件事,后五毫秒做一件事。并行:在同一时间点上同时执行,要实现并行必须是多核CPU才能完成。那我们如何实现并发呢?这个问题实际上很简单,无非就是我们使用多个线程去实现并发。2. 线程?进程?上文我们提到了线程,那原创 2022-05-30 23:05:27 · 291 阅读 · 0 评论 -
Java并发编程——CompletableFuture详解
Future/CallableJava 1.5开始,提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。Future接口可以构建异步应用,是多线程开发中常见的设计模式。当我们需要调用一个函数方法时。如果这个函数执行很慢,那么我们就要进行等待。但有时候,我们可能并不急着要结果。因此,我们可以让被调用者立即返回,让他在后台慢慢处理这个请求。对于调用者来说,则可以先处理一些其他任务,在真正需要数据的场合再去尝试获取需要的数据。简单实现public class Fut原创 2021-11-15 13:52:25 · 2514 阅读 · 0 评论 -
Java并发编程——线程池详解
背景在执行一个异步任务或并发任务时,往往是通过直接new Thread()方法来创建新的线程,这样做弊端较多。经常创建和销毁线程,对性能的影响很大(上下文切换)更好的解决方案是合理地利用线程池,线程池的优势很明显,如下:降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗;提高系统响应速度,当有任务到达时,无需等待新线程的创建便能立即执行;方便线程并发数的管控,线程若是无限制的创建,不仅会额外消耗大量系统资源,更是占用过多资源而阻塞系统或oom等状况,从而降低系统的稳定性。原创 2021-11-14 22:21:25 · 623 阅读 · 0 评论 -
Java并发编程——ConcurrentHashMap详解
引出场景:针对用户来做一个访问次数的记录。通过HashMap进行记录,key为用户名,value为访问次数。public class ConcurrentHashMapDemo { private static final HashMap<String, Integer> USER_ACCESS_COUNT = new HashMap<>(); public static void main(String[] args) { //针对用户来做原创 2021-11-14 15:19:44 · 11634 阅读 · 0 评论 -
Java并发编程——ForkJoin详解
概念Fork/Join 框架是 Java7 提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。类似于Java 8中的parallel Stream。【只能将任务1个切分为两个,不能切分为3个或其他数量】简单使用public class ForkJoinExample { //针对一个数字,做计算。 private static final Integer MAX = 200; static class原创 2021-11-13 19:26:19 · 12499 阅读 · 1 评论 -
Java并发编程——ThreadLocal详解
引出错误代码:public class ThreadLocalExample { //希望每一个线程获得的num都是0 private static int num = 0; public static void main(String[] args) { Thread[] threads = new Thread[5]; for (int i = 0; i < 5; i++) { threads[i] = new T原创 2021-11-12 22:44:34 · 1144 阅读 · 0 评论 -
JUC并发工具集:CountDownLatch、Semaphore、CyclicBarrier
CountDownLatch概念countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。简单使用下方代码为阻塞多个线程,只有当计数器为0的时候才会执行其他等待线程。开启三个线程,使其处于等待状态,只有主线程中将计数器-1,等待的线程才可以执行。public class CountDow原创 2021-11-12 13:09:17 · 675 阅读 · 0 评论 -
Java并发编程——线程通信Condition及其原理分析
线程通信使用 volatile 关键字基于 volatile 关键字来实现线程间相互通信是使用共享内存的思想,大致意思就是多个线程同时监听一个变量,当这个变量发生变化的时候 ,线程能够感知并执行相应的业务。这也是最简单的一种实现方式。public class VolatileShareDemo { // 定义一个共享变量来实现通信,它需要是volatile修饰,否则线程不能及时感知 static volatile boolean notice = false; public原创 2021-11-11 15:43:36 · 716 阅读 · 0 评论 -
Java并发编程——Lock及其原理分析
Lock 常用方法首先要说明的就是Lock,通过查看Lock的源码可知,Lock是一个接口:public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void un原创 2021-11-09 15:34:11 · 837 阅读 · 0 评论 -
Java并发编程——DCL问题
单例模式中的DCL问题我们都知道在程序执行过程中,java虚拟机为了速率,有可能会产生重排序。拿最普通的初始化一个实例来讲。他的过程如下:(1)分配内存;(2)初始化实例;(3)将实例指向该内存。但是由于重排序的特性,可能最终的执行方式是1->3->2。如此就会产生,还没有将实例中的变量初始化完毕,就已经分配了内存。此时该实例已经不为null,但是其中的成员变量,还没有初始化为指定值。当别的线程调用时,就会返回错误的结果。举个栗子,写一个单例模式中的双检查模式。public cla原创 2021-11-08 16:02:15 · 1145 阅读 · 3 评论 -
Java并发编程——JMM模型相关概念
在不同的CPU架构中,为了避免因为指令重排序、或者缓存一致性问题,都提供了不同的内存屏障指令。同时,在不同的操作系统中,也都会实现封装一个内存屏障的实现。那么,我们写的Java线程,如何能够在不同的硬件、不同操作系统下,仍然能够保证线程安全性呢?这就要引出JMM(Java 内存模型),它就是为了屏蔽操作系统和硬件的差异,让一套代码在不同平台下都能达到线程安全的访问目的。什么是JMM模型首先,我们都知道Java程序是运行在Java虚拟机上的,同时我们也知道,JVM是一个跨语言跨平台的实现,也就是Writ原创 2021-11-08 15:48:51 · 174 阅读 · 0 评论 -
并发编程—— volatile(数据一致性、重排序、伪共享等)
Volatile解决多线程环境中可见性问题通过缓存锁及内存屏障线程可见性问题public class VolatileDemo { public static boolean stop = false; public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { int i = 0; .原创 2021-11-07 16:13:11 · 504 阅读 · 0 评论 -
Java并发编程——Synchronized同步锁
原子性问题在下面的案例中,演示了两个线程分别去去调用 demo.incr 方法来对 i 这个变量进行叠加,预期结果应该是20000,但是实际结果却是小于等于20000的值。public class AutoDemo { int i = 0; // synchronized 排它锁 互斥锁 --- 同一时刻只能由一个线程执行 public synchronized void incr() { i++; } public static void原创 2021-11-06 19:44:09 · 527 阅读 · 0 评论 -
Java多线程的基本原理
进程与线程在学习Java多线程之前,我们需要搞清楚进程与线程之间的区别。进程是程序的一次动态执行过程,它需要经历从代码加载,代码执行到执行完毕的一个完整的过程,这个过程也是进程本身从产生,发展到最终消亡的过程。多进程操作系统能同时达运行多个进程(程序),由于 CPU 具备分时机制,所以每个进程都能循环获得自己的CPU 时间片。由于 CPU 执行速度非常快,使得所有程序好像是在同时运行一样。多线程是实现并发机制的一种有效手段。进程和线程一样,都是实现并发的一个基本单位。线程是比进程更小的执行单位,线程是原创 2021-11-05 18:03:23 · 1243 阅读 · 0 评论