
并发编程
文章平均质量分 66
并发编程
Andy_Health
永远不要停止奔跑。
展开
-
唤醒线程的三种方法
线程原创 2022-10-27 08:50:08 · 1988 阅读 · 0 评论 -
可重入锁 synchronized和 ReentranLock
可重入锁原创 2022-10-26 17:39:56 · 198 阅读 · 0 评论 -
并发编程 - Thread
ReentrantLock 在阻塞线程,用的是LockSupport.park()与这对应,唤醒线程,调用LockSupport.unpark()。可看源码时,会发现,调用LockSupport.park(),紧接着会调用Thread.interrupted(),Why?private final boolean parkAndCheckInterrupt() { LockSupport.park(this); // 阻塞线程 return Thread.interrupted();转载 2021-04-14 14:29:10 · 165 阅读 · 0 评论 -
并发编程 - AQS
它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用资源被阻塞时会进入此队列)。这里volatile是核心关键词。state的访问方式有三种:getState()setState()compareAndSetState()AQS定义两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)。不同的自定义同步器争用共享.转载 2021-04-14 13:35:28 · 203 阅读 · 0 评论 -
并发编程 - Java锁升级过程
一、锁种类偏向锁因为经过HotSpot的作者大量的研究发现,大多数时候是不存在锁竞争的,常常是一个线程多次获得同一个锁,因此如果每次都要竞争锁会增大很多没有必要付出的代价,为了降低获取锁的代价,才引入的偏向锁。轻量级锁轻量级锁考虑的是竞争锁对象的线程不多,而且线程持有锁的时间也不长的情景。因为阻塞线程需要CPU从用户态转到内核态,代价较大,如果刚刚阻塞不久这个锁就被释放了,那这个代价就有点得不偿失了,因此这个时候就干脆不阻塞这个线程,让它自旋这等待锁释放。自旋锁减少线程上下文切换,提高转载 2020-07-15 10:52:08 · 214 阅读 · 0 评论 -
并发编程 - 内存模型是如何保证原子性可见性有序性
原子性(操作是不可分、操作不可被中断): Synchronized、Lock可见性(保障数据的一致,数据安全一部分): Volatile、Synchronized有序性(按照自己想要执行的顺序执行线程): Join内存模型解决原子性、可见性、有序性原子性问题基本数据类型(byte short int float char boolean )的变量的读写操作已经自动保证原子性,使用Synchronized或者是ReentrantLock保证方法(静态方法,实例方法)和代码块的原子性。工作内存和主.原创 2020-06-30 21:51:39 · 214 阅读 · 0 评论 -
并发编程 - synchronized特性
可见性1)线程解锁前,必须把共享变量的最新值刷新到主内存中2)线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新获取最新的值(注意:加锁与解锁需要是同一把锁)原子性由于synchronized具有同步锁,所以它也具有原子性有序性java中通过synchronized提供的锁机制,确保了在加锁和解锁过程中的逻辑执行是单线程的,也就满足了符合as-if-serial语义,从而实现了有序性。as-if-serial语义 把单线程程序保护了起来,遵守as-if-seria原创 2020-05-19 21:34:42 · 184 阅读 · 0 评论 -
并发编程 - 锁的内存语义
当线程释放锁时,JMM 会把该线程对应的本地内存中的共享变量刷新到主内存中。当线程获取锁时,JMM 会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区代码必须从主内存中读取共享变量。synchronized 的实现原理Synchronized 在JVM 里的实现都是基于进入和退出Monitor 对象来实现方法同步和代码块同步,虽然具体实现细节不一样,但是都可以通过成对的Moni...原创 2020-04-22 20:47:49 · 174 阅读 · 0 评论 -
并发编程 - final 的内存语义
final 的两个重排序规则1、在构造函数内对一个final 域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。看write()方法,只包含一行代码obj = new FinalMemory();。这一行代码包含两个步骤:构造一个FinalMemory 类型的对象。把这个对象的引用赋值给引用变量obj。总结: 写final 域的重排序规则可以确保...原创 2020-04-22 20:34:46 · 251 阅读 · 0 评论 -
并发编程 - volatile内存语义
volatile 特性可以把对volatile 变量的单个读/写,看成是使用同一个锁对这些单个读/写操作做了同步可以看成可见性: 对一个volatile 变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。原子性: 对任意单个volatile 变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。volatile 的内存语义内存语义:可以简...原创 2020-04-22 20:24:08 · 398 阅读 · 0 评论 -
并发编程 - Java内存模型(JMM)
从抽象的角度来看,JMM 定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(Main Memory)中,每个线程都有一个私有的本地内存(Local Memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM 的一个抽象概念,并不真实存在。它涵盖了缓存、写缓冲区、寄存器以及其他的硬件和编译器优化。Java 内存模型带来的问题可见性问题左边CPU 中运行...原创 2020-04-21 20:20:40 · 214 阅读 · 0 评论 -
并发编程 - 线程的并发安全
当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在调用代码中不需要任何额外的同步或者协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。1. 线程封闭就是把对象封装到一个线程里,只有这一个线程能看到此对象。那么这个对象就算不是线程安全的也不会出现任何安全问题。ad-hoc 线程封闭:这是完全靠实现者控制的线程封闭,他的线程封闭完全靠实现者实现。...原创 2020-04-17 17:31:05 · 228 阅读 · 0 评论 -
并发编程 - 线程池
为什么要用线程池?第一:降低资源消耗第二:提高响应速度。第三:提高线程的可管理性。ThreadPoolExecutorExecutor 是一个接口,它是Executor 框架的基础,它将任务的提交与任务的执行分离开来。ExecutorService 接口继承了Executor,在其上做了一些shutdown()、submit()的扩展,可以说是真正的线程池接口;AbstractExe...原创 2020-04-17 16:40:06 · 152 阅读 · 0 评论 -
并发编程 - 阻塞队列BlockingQueue
在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。什么是阻塞队列1)支持阻塞的插入方法:意思是当队列满时,队列会阻塞插入元素的线程,直到队列不满。2)支持阻塞的移除方法:意思是在队列为空时,获取元素的线程会等...原创 2020-04-16 17:49:13 · 256 阅读 · 0 评论 -
并发编程 - Map常见问题
1. HashMap 和HashTable 有什么区别?①、HashMap 是线程不安全的,HashTable 是线程安全的;②、由于线程安全,所以HashTable 的效率比不上HashMap;③、HashMap 最多只允许一条记录的键为null,允许多条记录的值为null,而HashTable 不允许;④、HashMap 默认初始化数组的大小为16,HashTable 为11,前者扩容...原创 2020-04-16 17:12:45 · 188 阅读 · 0 评论 -
并发编程-并发容器
hash把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。常用HASH 函数:直接取余法、乘法取整法、平方取中法。处理冲突方法:开放寻址法再散列法链地址法(拉链法)ConcurrentHashMap1.7 中HashMap 死循环分析在多线程环境下,使用HashMap 进行put 操作会引起死循环,导致CPU 利用率...原创 2020-04-15 22:12:47 · 203 阅读 · 0 评论 -
并发编程-AbstractQueuedSynchronizer
用来构建锁或者其他同步组件的基础框架,它使用了一个int 成员变量表示同步状态,通过内置的FIFO(先进先出) 队列来完成资源获取线程的排队工作。AQS 使用方式和其中的设计模式AQS 的主要使用方式是继承,子类通过继承AQS 并实现它的抽象方法来管理同步状态,在AQS 里由一个int 型的state 来代表这个状态,在抽象方法的实现过程中免不了要对同步状态进行更改,这时就需要使用同步器提供的...原创 2020-04-14 17:28:26 · 211 阅读 · 0 评论 -
并发编程-显式锁
显式锁Java 程序是靠synchronized 关键字实现锁功能的,使用synchronized 关键字将会隐式地获取锁,但是它将锁的获取和释放固化了,也就是先获取再释放。Lock在finally 块中释放锁,目的是保证在获取到锁之后,最终能够被释放。ReentrantLock1. 锁的可重入简单地讲就是:“同一个线程对于已经获得到的锁,可以多次继续申请到该锁的使用权”。而sync...原创 2020-04-14 15:19:59 · 181 阅读 · 0 评论 -
并发编程-原子操作CAS
原子操作假定有两个操作A 和B,如果从执行A 的线程来看,当另一个线程执行B 时,要么将B 全部执行完,要么完全不执行B,那么A 和B 对彼此来说是原子的。实现CAS 的基本思路就是,如果这个地址上的值和期望的值相等,则给其赋予新值,否则不做任何事儿,但是要返回原值是多少。循环CAS 就是在一个循环里不断的做cas 操作,直到成功为止。实现线程的安全利用CPU 的多处理能力,实现硬件层面...原创 2020-04-13 17:04:09 · 254 阅读 · 0 评论 -
并发编程-并发工具类
Fork-Join分而治之:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。归并排序 :归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。工作密取: 即当前线程的Task 已经全被执行完毕,则自动取到其他线程的Task 池中取出Ta...原创 2020-04-13 16:40:43 · 188 阅读 · 0 评论 -
并发编程-线程共享与协作
什么是进程和线程进程是程序运行资源分配的最小单位:进程是操作系统进行资源分配的最小单位,其中资源包括:CPU、内存空间、磁盘IO 等线程是CPU 调度的最小单位,必须依赖于进程而存在:线程是进程的一个实体,是CPU 调度和分派的基本单位,它是比进程更小的、能独立运行的基本单位进程是并发执行的程序在执行过程中分配和管理资源的基本单位。线程是进程的一个执行单元,是比进程还要小的独立运行的基本单...原创 2020-04-10 16:10:35 · 241 阅读 · 0 评论