深入理解java多线程
今天你学习了么
这个作者很懒,什么都没留下…
展开
-
JUC - 为了线程安全 - 成熟工具类 - 原子类
1. 什么是原子类原子类的作用类似于锁,是为了保证并发情况下线程安全,不过原子类相对于锁有一定的优势:粒度更细:原子变量可以把竞争范围缩小到变量级别效率更高:通常使用原子类效率更高类型原子类Atomic*基本类型原子类AtomicInteger/AtomicLong/AtomicBooleanAtomic*Array数组类型原子类AtomicIntegerArray/AtomicLongArray/AtomicReferenceArrayAtomic*Refe原创 2020-12-11 11:14:14 · 509 阅读 · 0 评论 -
JUC - 管理线程提高效率 - 线程池
1. 线程池的重要性1.1 对于操作系统来说在操作系统创建线程、切换线程状态、终结线程都要进行CPU调度,进行上下文切换,这是一个耗费时间和系统资源的事情。大多数实际场景中是这样的:处理某一次请求的时间是非常短暂的,但是请求数量是巨大的。这种技术背景下,如果我们为每一个请求都单独创建一个线程,那么物理机的所有资源基本上都被操作系统创建线程、切换线程状态、销毁线程这些操作所占用,用于业务请求处理的资源反而减少了所以最理想的处理方式是,将处理请求的线程数量控制在一个范围,既保证后续的请求不会等待太长时间原创 2020-12-09 10:25:15 · 257 阅读 · 0 评论 -
并发编程 - 基础
1.1 进程和线程的定义进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,**进程是系统进行资源分配和调度的一个独立单位.**每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1–n个线程。(进程是资源分配的最小单位)线程:线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进原创 2020-12-08 22:06:47 · 68 阅读 · 0 评论 -
线程安全问题 - 发布与逸出
1. 逸出① private对象的逸出/** * 描述: 发布逸出 */public class MultiThreadsError3 { private Map<String, String> states; public MultiThreadsError3() { states = new HashMap<>(); states.put("1", "周一"); states.put("2",原创 2020-12-08 21:25:36 · 153 阅读 · 0 评论 -
Java内存模型和底层原理
1. 什么是JMMJMM:Java Memory Model,其实JMM并不像JVM内存结构一样是真实存在的。他只是一个抽象的概念;1.1 JMM是一组规范JMM是和多线程相关的,他描述了一组规则或规范,需要各个JVM的实现来遵守JMM规范,以便于开发者可以利用这些规范,更方便的开发多线程程序;如果没有这样的一个JMM内存模型来规范,那么很可能经过了不同JVM的不同规则的重排序以后,导致不同的虚拟机上运行的结果不一样,正是由于有了JMM,Java的并发编程才能避免很多问题。Java的内存模型不仅受原创 2020-12-07 21:43:35 · 335 阅读 · 0 评论 -
并发编程 - Thead和Object类中线程相关的方法
类方法名简介Threadsleep相关join等待其他线程执行完毕yield相关放弃已经获得到的CPU资源currentThread获取当前执行线程的引用start,run相关启动线程开关stop,suspend,resume相关已废弃Objectwait/notify/notifyAll让线程暂时休息和唤醒1. wait/notify/notifyAllwait/notify/notifyAll2. sleep...原创 2020-12-07 11:26:30 · 114 阅读 · 0 评论 -
生产者和消费者模式
1. 使用wait实现生产者消费者模式/** * 描述: 用wait/notify来实现生产者消费者模式 */public class ProducerConsumerModel { public static void main(String[] args) { EventStorage eventStorage = new EventStorage(); Producer producer = new Producer(eventStorage);原创 2020-12-07 09:47:37 · 69 阅读 · 0 评论 -
并发编程 - 线程的生命周期
new -> runnable(对应操作系统的ready和running两种状态) -> blocked(被阻塞,要进入synchronized代码但是拿不到锁) -> waiting(等待) -> timed waiting(计时等待) -> terminated public enum State { /** * Thread state for a thread which has not yet started.原创 2020-12-06 21:05:24 · 120 阅读 · 0 评论 -
并发编程 - 创建多线程的方法以及线程的启动与停止
1. 官方回答Oracle官方文档的描述是这样的There are two ways to create a new thread of execution. One is to declare a class to be a subclass of Thread. This subclass should override the run method of class Thread. An instance of the subclass can then be allocated and sta原创 2020-12-06 14:41:37 · 211 阅读 · 0 评论 -
CompletableFuture
使用CompletableFuture优化你的代码执行效率使用CompletableFutureJava8之Consumer、Supplier、Predicate和Function攻略1. 什么是CompletableFutureCompletableFuture用于异步编程,是对Future的扩展,Future被用于作为一个异步计算结果的引用,提供一个 isDone() 方法来检查计算任务是否完成。当任务完成时,使用get() 方法用来接收计算任务的结果,但是Future存在一些局限性无法手动原创 2020-07-15 16:34:53 · 205 阅读 · 0 评论 -
自己打造高性能缓存
1. 起步缓存是在实际生产中非常常用的工具,用了缓存以后,我们可以避免重复的计算,提高吞吐量;缓存乍一看简单,好像使用Map就可以实现,而初级的缓存的确是使用Map实现的,不过一个功能完备,性能强劲的缓存,就需要考虑更多的点了,先来看看使用最简单的HashMappublic class SimpleCache { private final HashMap<String, In...原创 2020-04-14 13:08:43 · 165 阅读 · 0 评论 -
以不变应万变
1. 不变性如果对象在被创建后,状态就不能被修改,那么他就是不可变的,不仅仅是对象的引用指向不可变,还包括成员变量等都是不可变的具有不可变特性的对象一定是线程安全的2. final根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率在早期final的作用和现在有所不同...原创 2020-04-14 09:34:56 · 202 阅读 · 0 评论 -
并发队列
1. 概述① 为什么要使用队列用队列可以在线程之间传递数据:生产者消费者模型,银行转账等地方假如队列是线程安全的,那么我们就不用考虑了,只需从中取或者添加使用就行了;那也就是说考虑锁等线程安全问题的重任从使用者转移到了队列上② 并发队列③ 阻塞队列阻塞队列是具有阻塞功能的队列,所以他首先是一个队列,其次是具有阻塞功能通常,阻塞的队列的一端是给生产者放数据用的,另一端是给消费者拿数据...原创 2020-04-01 11:54:26 · 103 阅读 · 0 评论 -
CopyOnWriteArrayList
1. 并发容器的概述对于ArrayList来说是线程不安全的,为了解决这个问题,JDK为我们提供了线程安全的并发容器① Vector 过时的同步容器Vector是早期为了解决ArrayList的线程不安全而实现的,它的实现方法很简单,在ArrayList的方法上都加上了Synchronized既然放在方法上锁住的是整个实例对象,可想而知这样的效率很低② Collections.sync...原创 2020-04-01 11:22:46 · 139 阅读 · 0 评论 -
JUC - 控制并发流程
1. 什么是控制并发流程在我们不控制并发的时候,线程进可能跑,受线程调度器控制,而不受程序员控制;如果我现在想让一些线程先执行,一些线程在最后执行,就要使用并发流程的工具类,让线程之间相互合作,来满足业务需求;比如让线程A等待线程B执行完再执行等策略类作用说明Semaphore信号量,可以通过控制许可证的数量来保证线程之间的配合线程只有在拿到许可证后才能继续运行...原创 2020-03-31 21:58:14 · 198 阅读 · 0 评论 -
锁的分类
大部分图片来源不可不说的Java“锁”事1. 乐观锁与悲观锁悲观锁(互斥同步锁)悲观锁的思想就是,如果我不锁住这个资源,别人就会来争抢,就会造成数据结果的错误,所以每次悲观锁就会为了保证结果的正确性,在每次获取并修改数据的时候把数据锁住,让别人无法访问数据(典型的就是synchronizd和lock),但是这样的思想会有缺陷① 阻塞和唤醒会带来性能的劣势在线程的挂起与唤醒会发生上下文切...原创 2020-03-31 13:17:33 · 199 阅读 · 0 评论 -
JUC - 为了线程安全 - 读写锁
1. 共享锁和排它锁排它锁排它锁又称独占锁,获得了以后既能读又能写,,其他没有获得锁的线程不能读也不能写,典型的xynchronized就是排它锁共享锁共享锁又称读锁,获得了共享锁以后可以查看但无法修改和删除数据,其他线程也能获得共享锁,也可以查看但不能修改和删除数据在没有读写锁之前,那么我们虽然保证了线程安全,但是也浪费了一定的资源,因为多个读操作同时进行并没有线程安全问题Reent...原创 2020-03-31 12:38:13 · 255 阅读 · 0 评论 -
线程池源码分析
Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理1. 线程池架构① 最顶层的是一个Executor接口,仅定义了一个方法② 随后是ExecutorService,继承自Executor的接口,做了方法的扩展,可以说是真正的线程池接口看里面有一个submit方法,也是用于提交线程的,但是我们看在顶级接口Executor中的execute也是...转载 2020-03-30 16:32:06 · 145 阅读 · 0 评论 -
JUC - 底层原理 - AQS
浅谈Java并发编程系列(九)—— AQS结构及原理分析1. AQS是干什么的最开始在jdk1.6以前只有synchronized的重量级锁,调用的是底层的native方法,也就是会去调用操作系统的函数,因为要操作操作系统的函数所以有用户态–>内核态的状态的切换,所以是重量级这个时候Doung Lea大哥看不惯了,开发了JUC这个包,让解决同步不要再去操作系统层面去做,可想而知比syn...原创 2020-03-22 23:00:28 · 430 阅读 · 0 评论 -
JVM内存结构 VS Java内存模型 VS Java对象模型
JVM内存结构 VS Java内存模型 VS Java对象模型1. JVM内存模型Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途。其中有些区域随着虚拟机进程的启动而存在,而有些区域则依赖用户线程的启动和结束而建立和销毁JVM内存结构,由Java虚拟机规范定义。描述的是Java程序执行过程中,由JVM管理...转载 2020-03-21 18:36:38 · 140 阅读 · 0 评论 -
线程安全问题和锁 - 锁
2. 阻塞式的解决方案(synchronized,lock)2.1 synchronizedsynchronized (对象){ //临界区}synchronized保证了临界区的代码的原子性总的说来,synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,synchronized可作用于instance变量、ob...原创 2020-03-21 15:47:17 · 209 阅读 · 0 评论 -
线程的通讯
多个线程并发执行时,在默认情况下CPU是随机切换线程的,有时我们希望CPU按我们的规律执行线程,此时就需要线程之间协调通信1. 线程通信的方式概述|--休眠唤醒方式: |--Object的wait、notify、notifyAll |--Condition的await、signal、signalAll|--CountDownLatch:用于某个线程A等待若干个其他线程执行完之后,它才执行...原创 2020-03-21 15:17:28 · 104 阅读 · 0 评论 -
线程顺序输出
1. 固定运行顺序必须先 2 后 1 打印1.1 wait¬ifypublic class WaitAndNotifyall { //用来同步的对象 public static Object lock = new Object(); // t2 运行标记, 代表 t2 是否执行过 public static boolean t2isprint = f...原创 2020-03-21 15:13:21 · 438 阅读 · 0 评论 -
Park & Unpark
Park & Unpark它们是 LockSupport 类中的方法// 暂停当前线程LockSupport.park(); // 恢复某个线程的运行 LockSupport.unpark(暂停线程对象)wait,notify 和 notifyAll 必须配合 Object Monitor 一起使用,而 park,unpark 不必park & unpa...原创 2020-03-21 15:02:01 · 363 阅读 · 0 评论 -
join
1. 为什么需要join()static int r = 0; public static void main(String[] args) throws InterruptedException { test1(); } private static void test1() throws InterruptedException { log.debug("开始");...原创 2020-03-21 14:32:13 · 147 阅读 · 0 评论 -
JUC - 为了线程安全 - 互斥同步 - ReentrantLock
ReentrantLock相对于 synchronized 它具备如下特点可中断 (可以在取消等待锁,终止等待)被动的避免死等对比synchronized,synchronized获得的锁不可中断,也就是说线程A一直在等待锁,可以让求他线程终止他的等待可以设置超时时间,被动的避免死等这个的意思是说,线程A等待锁,我们可以让大他再等待了一定时间后,如果还没等待的锁就放弃等待可...原创 2020-03-21 12:04:18 · 157 阅读 · 0 评论 -
wait和notify
wait和notifywait方法是当前拥有了锁的线程发现自己不满足自己想要的运行条件,于是释放锁,进入wait状态,等待满足条件以后被唤醒1. 为什么要使用wait和notify假设现在有一些员工(线程)要使用同一把算盘(共享资源)工作,为了保证线程的安全性,他们的老板就设置了一个房间(synchronized锁),在一个时间只有一个线程可以进入这个房间进行工作,但是现在,有一个员工小南进...原创 2020-03-21 10:35:04 · 129 阅读 · 0 评论 -
死锁
死锁死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程(线程)称为死锁进程(线程)。多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。如下图所示,线程 A 持有资源 2,线程 B ...原创 2020-03-21 09:01:06 · 477 阅读 · 0 评论 -
Future - 获取子线程执行结果
1. 为什么要Future机制对比常见的两种创建线程的方式,一种是直接继承Thread,另外一种就是实现Runnable接口,他们在执行完任务之后无法获取执行结果,从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果Future模式的核心思想是能够让主线程将原来需要同步等待的这段时间用来做其他的事情。(因为可以异步获得执行结果,所以不用...原创 2020-03-07 21:42:11 · 1369 阅读 · 0 评论 -
ThreadPoolExecutor
① ExecutorService是线程池最基础的接口② ScheduledExecutorService在ExecutorService的基础上添加了任务调度功能1. 线程池状态ThreadPoolExecutor 使用 int 的高 3 位来表示线程池状态,低 29 位表示线程数量状态名高3位接收新任务处理阻塞队列任务说明RUNNING111YY线程...原创 2020-03-07 20:21:41 · 320 阅读 · 0 评论 -
线程安全问题和锁 - 线程安全问题
1. 变量的线程安全问题临界区: 多个线程对共享资源的读写操作时发生指令交错,就会出现问题,一段代码如果出现对共享资源的多线程读写操作,这段代码称为临界区竞态条件: 多个线程在临界区内执行,由于代码的执行序列不同而导致结果无法预测,称之为发生了竞态条件1.1 成员变量和静态变量是否是线程安全的如果没有共享,则是线程安全的如果被共享了,根据他们的状态是否能够改变,分为两种状态① ...原创 2020-03-05 18:21:22 · 266 阅读 · 0 评论 -
JUC - 为了线程安全 - 避免变量共享 - ThreadLocal
ThreadLocal和synchronized的区别正确理解Thread Local的原理与适用场景ThreadLocal详解1. 概述ThreadLocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度1.1 为什么需要Threadlocal举个例子,我出门需要先坐公交再做地铁,这里的坐公交和坐地铁就好...原创 2020-03-03 14:02:05 · 311 阅读 · 0 评论 -
自定义线程池
自定义线程池Blocking Queue是一个阻塞队列,是生产者消费者模型下的平衡双方速度差异的队列线程池一方是任务的消费者,不断获取任务来执行原创 2020-02-24 22:05:35 · 187 阅读 · 0 评论 -
享元模式 自定义连接池
一个线上商城应用,QPS 达到数千,如果每次都重新创建和关闭数据库连接,性能会受到极大影响。 这时 预先创建好一批连接,放入连接池。一次请求到达后,从连接池获取连接,使用完毕后再还回连接池,这样既节约 了连接的创建和关闭时间,也实现了连接的重用,不至于让庞大的连接数压垮数据库package ConnectedPool;import java.sql.*;import java.util.M...原创 2020-02-24 19:53:59 · 196 阅读 · 0 评论 -
为了线程安全 - 乐观锁 - 无锁并发
1. CAS可以是要无锁来实现实现遍历的同步问题class AccountSafe implements Account { private AtomicInteger balance; public void withdraw(Integer amount) { // 需要不断尝试,直到成功为止 while (true) { ...原创 2020-02-23 23:21:21 · 290 阅读 · 0 评论 -
为了线程安全 - 互斥同步 - Synchronized
**临界区:多个线程对共享资源的读写操作时发生指令交错,就会出现问题,一段代码如果出现对共享资源的多线程读写操作,这段代码称为临界区**竞态条件:**多个线程在临界区内执行,由于代码的执行序列不同而导致结果无法预测,称之为发生了竞态条件1. 阻塞式的解决方案(synchronized,lock)1.1 synchronizedsynchronized (对象){ //临界区}syn...原创 2020-02-18 19:23:07 · 432 阅读 · 0 评论 -
多线程的设计模式
1. 两阶段终止模式Two Phase Termination在线程T1中优雅的终止线程T2,优雅的意思是给线程T1一个料理后事的计划1.1 错误思路直接使用stop()来强制杀死线程:这样如果线程锁住了某一个共享资源,他被强制杀死就没有机会释放锁,其他的线程没法获得锁使用System.exit(int):这个直接杀死了进程,也不是我们想要的1.2 两阶段终止模式可以用在...原创 2020-02-17 21:51:12 · 130 阅读 · 0 评论 -
Java高并发编程
1. 一个synchronized代码块就是一个原子操作,不可分2. 为什么会产生脏读比如有一个银行存款程序,我们只对存钱加锁而对取钱不加锁,那么会出现脏读的问题public class Account { private String name; private double money; public synchronized void set(String n...原创 2020-02-16 21:42:53 · 212 阅读 · 0 评论