![](https://img-blog.csdnimg.cn/20201014180756724.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
并发编程
文章平均质量分 53
会new对象的Java工程师
佛祖保佑,永无bug
展开
-
进程与线程
程序是一组指令的集合,它描述了完成特定任务的步骤和操作。程序通常以源代码的形式编写,可以使用编程语言如C、Java、Python等来表示。程序本身是,它只是存储在存储介质(如硬盘)上的一段代码。进程是计算机系统中的实例。当一个程序被执行时,操作系统会为其创建一个独立的进程。线程是。一个进程可以包含多个线程,它们共享进程的内存空间和系统资源。线程是操作系统调度的基本单位,可以并发执行。原创 2023-07-28 17:39:08 · 189 阅读 · 0 评论 -
【并发编程】ThreadLocal
TreadLocalMap 使用 ThreadLocal 的弱引用作为 key,如果一个 ThreadLocal不存在外部强引用时,Key(ThreadLocal)势必会被 GC 回收,这样就会导致ThreadLocalMap 中 key 为 null, 而 value 还存在着强引用,只有 thead 线程退出以后,value 的强引用链条才会断掉。最终的变量是放在了当前线程的ThreadLocalMap中 ,并不是存在 ThreadLocal 上,ThreadLocal 作为 key。原创 2023-07-28 00:49:46 · 498 阅读 · 0 评论 -
【并发编程】线程池
直到线程池中的线程数不大于 corePoolSize,即当线程池中的线程数大于 corePoolSize 时,如果一个线程空闲的时间达到 keepAliveTime,则会终止,直到线程池中的线程数不超过 corePoolSize。在创建了线程池后,默认情况下,在创建了线程池后,线程池中的线程数为 0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目。如果线程池中存活的核心线程数小于线程数 corePoolSize 时,线程池会创建一个核心线程去处理提交的任务。原创 2023-07-28 00:43:27 · 95 阅读 · 0 评论 -
ConcurrentHashMap
ConcurrentHashmap 和 Hashtable 都是支持并发的,这样会有一个问题,当你通过 get(k)获取对应的 value 时,如果获取到的是 null 时,你无法判断,它是 put(k,v)的时候 value 为 null,还是这个 key 从来没有做过映射。jdk8 放弃了分段锁而是用了 Node 锁,减低锁的粒度,提高性能,并使用 CAS 操作来确保 Node 的一些操作的原子性,取代了锁。里面是模糊不清的,所以压根就不让 put null。,分段锁反而会造成更新等操作的长时间等待。原创 2023-07-28 00:42:17 · 264 阅读 · 0 评论 -
ReentrantLock 锁实现
ReentrantLock 是 java.util.concurrent.locks 包下的类 , 实现 Lock 接口。NonfairSync 类继承了 Sync 类,表示采用非公平策略获取锁,其实现了 Sync 类中抽象的 lock 方法。FairSync 类也继承了 Sync 类,表示采用公平策略获取锁,其实现了 Sync 类中的抽象 lock 方法。来对共享资源进行同步,同时和 synchronized 一样,ReentrantLock。,除此之外,ReentrantLock 在调度上。原创 2023-07-25 15:07:33 · 99 阅读 · 0 评论 -
【并发编程】AQS
AQS 的全称为( AbstractQueuedSynchronizer ), 这个类在 java.util.concurrent.locks 包下面。AQS 是一个用来的框架,使用 AQS 能简单且高效地构造出同步器 , 是 JUC 中 核 心 的 组 件 ,比如我们提到的ReentrantLock,CountDownLatch 等等都是基于 AQS 来实现。只要搞懂了 AQS,那么 JUC 中绝大部分的 api 都能掌握。在内部有一个变量表示。原创 2023-07-25 15:02:32 · 90 阅读 · 0 评论 -
synchronized 锁实现
当方法调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,该标记表明线程进入该方法时,需要 monitorenter,退出该方法时需要 monitorexit。,线程代码执行在进入 synchronized 代码块时候会自动获取内部锁,这个时候其他线程访问时候会被阻塞,直到进入 synchronized 中的代码执行完毕或者抛出异常或者调用了 wait 方法,都会释放锁资源。当前线程拥有了这个对象的锁,把锁的计数器+1;当计数器为 0 时,锁就被释放了。原创 2023-07-25 14:56:59 · 58 阅读 · 0 评论 -
Java 中的锁分类
乐观锁在 Java 中的使用,是无锁编程,常常采用的是 CAS 算法,典型的例子就是原子类,通过 CAS 自旋实现原子操作的更新。重量级锁是指当锁为轻量级锁的时候,另一个线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数的时候,还没有获取到锁,就会。轻量级锁是指当锁是偏向锁的时候,此时又有一个线程访问,偏向锁就会升级为轻量级锁,其他线程会通过。由此可见,自旋锁是是比较消耗 CPU 的,因为要不断的循环重试,不会释放 CPU资源。读锁的共享锁可保证并发读是非常高效的,读写,写读 ,写写的过程是互斥的。原创 2023-07-22 14:48:20 · 38 阅读 · 0 评论 -
【并发编程】CAS
如原先的内存值为(A,1),线程将(A,1)修改为了(B,2),再由(B,2)修改为(A,3)。此时另一个线程使用预期值(A,1)与内存值(A,3)进行比较, 只需要比较版本号 1 和 3,即可发现该内存中的数据被更新过了。每次判断我的预期值和内存中的值是不是相同,如果不相同则说明该内存值已经被其他线程更新过了,因此需要拿到该最新值作为预期值,重新判断。当另外一个线程使用预期值去判断时,预期值与内存值相同,当前线程的 CAS 操作无法分辨当前 V 值是否发生过变化。的一种实现方式,他采用的是。原创 2023-07-22 14:45:33 · 60 阅读 · 0 评论 -
原子性的实现
synchronized 一定能保证原子性,因为被 synchronized 修饰某段代码后,无论是单核 CPU 还是多核 CPU,只有一个线程能够执行该代码,所以一定能保证原子操作。也就是说,一个获得锁的线程被CPU切换走了,即使其他线程来访问这段临界资源,由于锁被占用,也无法访问。synchronized 来保证原子性。:进程只能一个一个的执行,同时有多个进程,那么根据一定的规则(调度算法)选取一个执行,其他先等待。,例如Java 语言提供的 synchronized 关键字,就是锁的一种实现。原创 2023-07-22 14:40:50 · 104 阅读 · 0 评论 -
Volatile关键字
被volatile修饰的共享变量,对其他线程是可见的。禁止指令重排。volatile不能保证对变量操作的原子性。volatile可以解决不可见性和无序性,但不能保证原子性。原创 2023-07-22 14:39:03 · 42 阅读 · 0 评论 -
【并发编程】安全问题
缓存导致的可见性问题,编译优化带来的有序性问题,线程切换带来的原子性问题,。其实缓存、线程、编译优化的目的和我们写并发程序的目的是相同的,都是提高程序安全性和性能。但是技术在解决一个问题的同时,必然会带来另外一个问题,所以在采用一项技术的同时,一定要清楚它带来的问题是什么,以及如何规避。原创 2023-07-21 18:23:05 · 38 阅读 · 0 评论 -
Java内存模型(JMM)
Java 虚拟机是一个完整的计算机的一个模型,因此这个模型自然也包含一个内存模型——又称为 Java 内存模型。这里的工作内存是 JMM 的一个抽象概念,也叫本地内存,其存储了该线程读 / 写共享变量的副本。,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。Java 内存模型(Java Memory Model,JMM)Java 内存模型中规定了所有的变量都存储在。原创 2023-07-21 18:21:46 · 45 阅读 · 0 评论