Java高并发编程-(五)共享模型之管程 死锁、哲学家就餐问题、ReentrantLock (锁重入、锁超时、可中断、公平锁、条件变量)、同步模式之顺序控制
Java并发编程(五) (共享模型之管程)_ 死锁、哲学家就餐问题、ReentrantLock (锁重入、锁超时、可中断、公平锁、条件变量)、同步模式之顺序控制· 一、多把锁· 小故事 一间大屋子有两个功能:睡觉、学习,互不相干。 现在小南要学习,小女要睡觉,但如果只用一间屋子(一个对象锁)的话,那么并发度很低 小南获得锁之后, 学完习之后, 小女才能进来睡觉。 解决方法是准备多个房间(多个对象锁) 1234567891011121314151617181920212223242526@Slf4j(topic = "guizy.BigRoomTest")public class BigRoomTest { public static void main(String[] args) { BigRoom bigRoom = new BigRoom(); new Thread(() -> bigRoom.sleep(), "小南").start(); new Thread(() -> bigRoom.study(), ...
Java高并发编程-(四)共享模型之管程 wait和notify原理、同步模式之保护性暂停、异步模式之生产者_消费者、park和unpark原理、线程状态转换
Java并发编程(四) (共享模型之管程)_ wait和notify原理、同步模式之保护性暂停、异步模式之生产者_消费者、park和unpark原理、线程状态转换· 一、 wait和notify (重点)· 1、小故事· 2、wait、notify介绍 (必须要获取到锁对象, 才能调用这些方法)· 当线程0获得到了锁, 成为Monitor的Owner, 但是此时它发现自己想要执行synchroized代码块的条件不满足; 此时它就调用obj.wait方法, 进入到Monitor中的WaitSet集合, 此时线程0的状态就变为WAITING 处于BLOCKED和WAITING状态的线程都为阻塞状态,CPU都不会分给他们时间片。但是有所区别: BLOCKED状态的线程是在竞争锁对象时,发现Monitor的Owner已经是别的线程了 ,此时就会进入EntryList中,并处于BLOCKED状态 WAITING状态的线程是获得了对象的锁,但是自身的原因无法执行synchroized的临界区资源需要进入阻塞状态时,锁对象调用了wait方法而进入了WaitSet中,处于WAITING状态 ...
Java高并发编程-(十一)JUC 之 ReentrantReadWriteLock、StampedLock、Semaphore(信号量)、CountdownLatch、CyclicBarrier
Java并发编程(十一) : JUC 之 ReentrantReadWriteLock、StampedLock、Semaphore(信号量)、CountdownLatch、CyclicBarrier· ReentrantReadWriteLock· 当读操作远远高于写操作时,这时候使用 读写锁 让 读-读 可以并发,提高性能。 类似于数据库中的 select ... from ... lock in share mode提供一个 数据容器类 内部分别使用读锁保护数据的 read() 方法,写锁保护数据的 write() 方法 1234567891011121314151617181920212223242526272829303132class DataContainer { private Object data; private ReentrantReadWriteLock rw = new ReentrantReadWriteLock(); private ReentrantReadWriteLock.ReadLock r = rw.readLock(); ...
Java高并发编程-(十二)JUC 之线程安全集合类 ConcurrentHashMap、BlockingQueue、ConcurrentLinkedQueue、CopyOnWriteArrayList
Java并发编程(十二)(线程安全集合类) : JUC线程安全集合类 ConcurrentHashMap、BlockingQueue、ConcurrentLinkedQueue、CopyOnWriteArrayList· 线程安全集合类概述· 线程安全集合类可以分为三大类: 遗留的线程安全集合如 Hashtable , Vector 使用 Collections 装饰的线程安全集合,如: Collections.synchronizedCollection Collections.synchronizedList Collections.synchronizedMap Collections.synchronizedSet Collections.synchronizedNavigableMap Collections.synchronizedNavigableSet Collections.synchronizedSortedMap Collections.synchronizedSortedSet java.util.concurr ...
Java高并发编程-(十)共享模型之工具 JUC 之 AQS原理、ReentrantLock原理
Java并发编程(十)(Java 并发工具包) _ JUC 之 AQS原理、ReentrantLock原理· 一、AQS 原理· 什么是AQS及其原理 1、AQS简介· AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。 · 特点: 用 state 属性来表示资源的状态(分独占模式和共享模式),子类需要定义如何维护这个状态,控制如何获取锁和释放锁 getState - 获取 state 状态 setState - 设置 state 状态 compareAndSetState - cas 机制设置 state 状态 独占模式是只有一个线程能够访问资源,而共享模式可以允许多个线程访问资源 提供了基于 FIFO 的等待队列,类似于 Monitor 的 EntryList 条件变量来实现等待、唤醒机制,支持多个条件变量,类似于 Monitor 的 WaitSe ...
Java高并发编程-(七)共享模型之无锁 CAS概念、原子操作类、LongAddr原子累加器、Unsafe
Java并发编程(七) (共享模型之无锁)_ CAS概念、原子操作类、LongAddr原子累加器、Unsafe· 一、 共享模型之无锁· Java中 synchronized 和 ReentrantLock 等 独占锁 就是 悲观锁 思想的实现 在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式 CAS 实现的 管程即monitor是阻塞式的悲观锁实现并发控制,这章我们将通过非阻塞式的乐观锁的来实现并发控制 1、 问题提出· 有如下需求,保证account.withdraw取款方法的线程安全, 下面使用synchronized保证线程安全 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273/** * Description: 使用重量级锁synchronized来保证多线程访问共享资源发生的安全 ...
Java高并发编程-(六)共享模型之内存 Java内存模型(JMM-原子性、可见性、有序性)、volatile原理、volatile保证可见性, 有序性、单例设计模式
Java并发编程(六) (共享模型之内存)_ Java内存模型(JMM-原子性、可见性、有序性)、volatile原理、volatile保证可见性, 有序性、单例设计模式(各种实现分析)· 多线程的三大特性 (原子性、可见性、有序性) 之前讲的synchronized底层Monitor主要关注的是访问共享变量时,保证临界区代码的 原子性 。下面进一步深入学习共享变量在多线程间的【可见性】问题与多条指令执行时的【有序性】问题 一、 Java 内存模型 (重点)· JMM 即 Java Memory Model ,它从Java层面定义了 主存、工作内存 抽象概念,底层对应着CPU 寄存器、缓存、硬件内存、CPU 指令优化等。JMM 体现在以下几个方面 原子性 - 保证指令不会受 线程上下文切换的影响 可见性 - 保证指令不会受 cpu 缓存的影响 (JIT对热点代码的缓存优化) 有序性 - 保证指令不会受 cpu 指令并行优化的影响 1、 可见性 (重点)· 1.1、退不出的循环· 先来看一个现象,main线程对run变量的修改对于t线程不可见,导致了 t 线程无法停止 ...
Java高并发编程-(九)共享模型之工具 线程池详解、ThreadPoolExecutor、ScheduledExecutorService、Fork_Join
Java并发编程(九)(共享模型之工具) _ 线程池详解、ThreadPoolExecutor、ScheduledExecutorService、Fork_Join· 1、线程池 (重点)· 池化技术有很多, 比如线程池、数据库连接池、HTTP连接池等等都是对这个思想的应用。池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。 线程池提供了一种 限制和管理资源(包括执行一个任务)。 每个线程池还维护一些基本统计信息,例如已完成任务的数量。这里借用 《Java 并发编程的艺术》 提到的来说一下使用线程池的好处: 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 (创建的线程,实际最后要和操作系统的线程做映射,很消耗资源) 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。 1.1、 自定义一个简单的线程池· 图解· 阻塞队列中维护了由主线程(或者其他线程)所产生的的任务 主线程 ...
Java高并发编程-(八)共享模型之不可变 不可变对象设计(String保护性拷贝)、final的使用、享元模式
Java并发编程(八) (共享模型之不可变) _ 不可变对象设计(String保护性拷贝)、final的使用、享元模式· 一、 不可变类设计 String· 如果一个对象在不能够修改其内部状态(属性),那么它就是线程安全的,因为不存在并发修改 类用 final 修饰保证了该类中的方法不能被覆盖,防止子类无意间破坏不可变性 不可变 如果一个对象在不能够修改其内部状态(属性),那么它就是线程安全的,因为 不存在并发修改。 1、日期转换的问题· 问题提出 下面的代码在运行时,由于 SimpleDateFormat 不是线程安全的 1234567891011SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");for (int i = 0; i < 10; i++) { new Thread(() -> { try { log.debug("{}", sdf.parse("1951-04-21")); } catch (Exception e) { log.error("{}", e); } ...
Java高并发编程-(一)线程与进程、并行并发、同步异步概念
Java 高并发编程 一 线程与进程、并行并发、同步异步概念· 一、线程与进程、并行并发、同步异步概念· 1、进程与进程· 进程: 资源分配的最小单位进程是线程的容器, 一个进程中包含多个线程, 真正执行任务的是线程线程: 资源调度的最小单位 进程· 程序由指令和数据组成,但是这些 指令要运行,数据要读写,就必须将指令加载到cpu,数据加载至内存。在指令运行过程中还需要用到磁盘,网络等设备,进程就是用来加载指令,管理内存,管理IO的 当一个指令被运行,从磁盘加载这个程序的代码到内存,这时候就开启了一个进程 进程就可以视为程序的一个实例,大部分程序都可以运行多个实例进程(例如记事本,浏览器等),部分只可以运行一个实例进程(例如360安全卫士) 线程· 一个进程之内可以分为多个线程。 一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给 CPU 执行 Java 中,线程作为资源的最小调度单位,进程作为资源分配的最小单位。 在 windows 中进程是不活动的,只是作为线程的容器。 二者对比· 进程基本上相互独立的,而线程存在于进程内,是进程的一个子集 进程拥有共享 ...