
并发编程
文章平均质量分 89
Java硬件工程师
中国科学技术大学毕业,原支付宝Java开发工程师,立志做一名资深全栈工程师
展开
-
JUC之AQS
可重入锁可重入锁理论可重入锁又名递归锁,是指在同一个线程在外层方法获取锁的时候,再进入该线程的的内层方法会自动获取锁(前提是锁对象得是同一个对象),不会因为之前已经获取过还没释放而阻塞。Java中ReentrantLock和synchronized都是可重入锁,可重入锁的一个优点是可一定程度避免死锁。将字分开解释:可:可以重:再次入:进入锁:同步锁进入什么? - 进入同步域(即同步代码块/方法或显示锁锁定的代码)一个线程中的多个流程可以获取同一把锁,持有这把同步锁可以再次进入。自己可以原创 2022-03-30 22:09:12 · 258 阅读 · 0 评论 -
深入理解HashMap+ConcurrrentHashMap扩容的原理
关于HashMap和ConcurrentHashMap的内容,可以参看Java基础-HashMap集合。Java并发编程-ConcurrentHashMap。这两篇文章,本章将深入探讨两者JDK1.7和JDK1.8两个版本的扩容机制。1.JDK1.7版本的HashMap扩容机制HashMap的初始化容量是16,默认加载因子是0.75,扩容时扩容到原来的两倍,这些特性对于其它版本的hashMap和concurrentHashMap同样满足。当hashmap中的元素个数超过数组大小加载因子loadFacto原创 2021-02-06 21:37:03 · 3193 阅读 · 2 评论 -
Java并发编程-ConcurrentHashMap
1. JDK 7 HashMap 并发死链1.1.HashMap回顾关于HashMap的具体特性可以参看HashMap集合HashMap是由数组+链表构成的,链表用来解决哈希冲突的情况。注意:在JDK8里,后加入链表的元素被放入到链表的尾部,在JDK7里,后加入链表的元素被返给到链表的头部。这是死链产生的重要原因。死链发生在扩容时,随着数组中的元素越来越多,链表的长度就会越来越长,这样性能就会受到影响。所以在JDK7和JDK8里都会在数组元素超过阈值时,即数组长度的3/4,它会进行一次扩容,扩容会原创 2021-02-06 15:02:39 · 3616 阅读 · 12 评论 -
Java并发编程-ReentrantLock可重入锁
目录1.ReentrantLock可重入锁概述2.可重入3.可打断4.锁超时5.公平锁6.条件变量 Condition1.ReentrantLock可重入锁概述相对于 synchronized 它具备如下特点可中断synchronized锁加上去不能中断,a线程应用锁,b线程不能取消掉它可以设置超时时间synchronized它去获取锁时,如果对方持有锁,那么它就会进入entryList一直等待下去。而可重入锁可以设置超时时间,规定时间内如果获取不到锁,就放弃锁可以设置为公平锁防止线程饥饿的原创 2021-02-05 19:51:42 · 1836 阅读 · 7 评论 -
Java并发编程-wait和notify原理剖析
1.小故事 - 为什么需要 wait有一对小孩都要使用算盘CPU进行计算,为了计算过程中的计算安全,老王设计了一个synchronized锁,让每个时刻只有一个线程进入房间成为owner的主人。这样只能排队一个一个线程的来,从而保证计算过程中的线程安全。由于条件不满足,小南不能继续进行计算(比如他必须要叼根烟,有烟才能进行计算)但小南如果一直占用着锁,其它人就得一直阻塞,效率太低于是老王单开了一间休息室(调用 wait 方法),让小南到休息室(WaitSet)等着去了,但这时锁释放开,其它人可以由原创 2021-02-05 17:10:38 · 2221 阅读 · 3 评论 -
Java并发编程-线程的状态
1.五种状态(操作系统角度)以下是从操作系统层面来描述的**[初始状态]**仅是在语言层面创建 了线程对象, 还未与操作系统线程关联.[可运行状态] (就绪状态)指该线程已经被创建(与操作系统线程关联), 可以由CPU调度执行[运行状态]指获取了CPU时间片运行中的状态当CPU时间片用完,会从[运行状态]转换至[可运行状态],会导致线程的上下文切换如果调用了阻塞API,如BIO读写文件,这时该线程实际不会用到CPU,会导致线程上下文切换[阻塞状态]等BIO操作完毕,会由操作系统唤醒阻塞的原创 2021-02-05 16:07:34 · 1240 阅读 · 4 评论 -
Java并发编程-synchronized锁优化
1.小故事synchronized工作方式是让每个对象关联一个monitor,monitor锁是由操作系统提供的,要使用它成本较高,如果是每次进入synchronized的话需要获得一个monitor锁,那么就需要很大的开销。从Java6开始对synchronized获取锁的方式进行了优化。除了可以使用轻量级锁,还可以使用偏向级锁来进行优化。故事角色老王 - JVM小南 - 线程小女 - 线程房间 - 对象房间门上 - 防盗锁 - Monitor房间门上 - 小南书包原创 2021-02-05 15:01:30 · 4115 阅读 · 5 评论 -
Java并发编程-synchronized底层原理
synchronized底层原理与Monitor密切相关1.Java对象头以 32 位虚拟机为例普通对象对象的类型,如Student类型,Teacher类型等是由KlassWord来表示的,它是一个指针,指向了对象所从属的Class。即找到类。其中 Mark Word 结构为其中,age表示垃圾回收时的分代年龄,具体可见分代收集算法。年龄超过一定岁数就从幸存区调入到老年代。最后两位,biased_lock和01表示偏向锁和加锁状态。其它表示在不同状态下每一位所代表的含义。Normal状态表示原创 2021-02-04 22:30:44 · 2546 阅读 · 9 评论 -
Java并发编程-线程池底层工作原理
关于线程池的具体介绍,可以参看ThreadPool线程池,这里主要介绍线程池底层工作原理。1.线程池的底层工作原理1.1.线程池的底层工作原理图线程池的主要处理原理图和流程图如下1.2.银行办理业务案例为了便于理解,我们用银行的例子来说明银行网=线程池corePoolsize=今日当值窗口。今日当值窗口由两个,当银行客人来了之后,先去候客厅等着,现在来了3个即3,4,5都来了,在候客厅等着,此时候客区也满了。突然,6,7,8三个人又来了,由于候客区也满了,此时可以用到maximumPoolS原创 2021-01-29 19:36:57 · 2531 阅读 · 5 评论 -
Java并发编程-ThreadPool线程池
1.线程池的优势1.1.引言与数据库线程池类似,如果没有数据库连接池,那么每次对数据库的连接池都要new来获取连接池。重复的连接和释放操作会消费大量的系统资源,我们可以使用数据库连接池,直接去池中取连接池。同样,在没有线程池之前,我们也是通过new Thread.start()来获取线程,现在我们也不需要new了,这样就能实现复用,使得我们系统变得更加高效。1.2.为什么要使用线程池例子:10年前单核CPU电脑,假的多线程,像马戏团小丑玩多个球,CPU需要来回切换。现在是多核电脑,多个线程各原创 2021-01-29 13:56:39 · 5475 阅读 · 7 评论 -
Java并发编程-BlockingQueue阻塞队列
1.BlockingQueue介绍1.1.引言:阻塞虽然是不好的,但是我们有时候不得不阻塞,比如说一家餐厅人满了,店主当然不希望即将过来的这些客人全部都走,而是希望它们留下来继续排队等候。对于阻塞的内容,线程和资源的调度管理能力,这样就出了一个接口,就叫阻塞队列。在不得不阻塞,必须要阻塞的时候,如何管理好被阻塞的资源和线程,这就是阻塞队列。队列的特性:先进先出,插入元素在队尾,删除元素在队头。1.2.阻塞队列介绍:阻塞:必须要阻塞/不得不阻塞阻塞队列是一个队列,在数据结构中中起的作用如下图:原创 2021-01-28 22:26:42 · 4101 阅读 · 6 评论 -
Java并发编程-ReadWriteLock读写锁
为什么我们有了Lock,还要用ReadWriteLock呢。我们对共享资源加锁之后,所有的线程都将会等待。Lock读操作也锁,写操作也会锁,而对共享资源读的时候,其实是不用加锁的。当然读写同时存在的情况也会有。比如我们数据库常用操作有增删改查,增删改都是写操作,写操作必须加锁。...原创 2021-01-28 18:26:15 · 2610 阅读 · 9 评论 -
Java并发编程-常用的辅助类
常用的辅助类1.CountDownLatch1.2.示例:班长锁门问题1.2.CountDownLatch类简介:1.2.1 CountDownLatch概念1.2.3 CountDownLatch的用法1.3.CountDownLatch案例:1.4.原理总结2.CyclicBarrier2.1.CyclicBarrier简介2.2.案例:集齐7颗龙珠召唤神龙3.Semophore3.1.Semophore简介3.2.抢车位问题3.3.原理总结1.CountDownLatch1.2.示例:班长锁门问题原创 2021-01-28 13:11:29 · 3486 阅读 · 13 评论 -
Java并发编程系列
Java并发基础1.多线程基础2.线程安全基础Java并发编程1.Lock锁与生产者消费者问题2.八锁问题带你彻底理解对象锁和类锁3.集合类的线程安全问题原创 2021-01-26 16:37:53 · 2059 阅读 · 3 评论 -
Java并发编程-集合类的线程安全问题
1.List集合的线程安全问题1.ArrayList线程安全问题。ArrayList是线程安全的吗,我们不妨运行以下的程序public static void main(String[] args) { // TODO Auto-generated method stub List<String> list=new ArrayList<>(); for(int i=1;i<=3;i++){ new Thread(()->{ //生成一个8位原创 2021-01-15 16:59:33 · 5514 阅读 · 9 评论 -
Java并发编程-八锁问题带你彻底理解对象锁和类锁
8锁问题演示1.标准访问标准访问,先打印邮件还是短信.不一定谁先被打印。取决于CPU的执行情况.激活他们的是main线程,后面谁先被调度,不知道。为了保证效果,我们在A和B的代码之间加thread.sleep(100).此时,可以确保A先被打印。解释:进入到main方法中之后,就是A找邮件,B找短信的方法。加完锁之后,同时进来,各回各家,各找各妈。因为我们人为的在A和B之间加了休眠时间,那么A肯定发生在B之前。按照标准访问。此时先打印邮件/*手机类可以发邮件和发短信*/class Phone原创 2021-01-15 11:07:20 · 2238 阅读 · 10 评论 -
Java并发编程-Lock锁与生产者消费者问题
传统Synchronized锁实现一个基本的售票例子:/*真正的多线程开发,公司中的开发,降低耦合性线程就是一个单独的资源类,没有任何附属的操作1.属性,方法 * */public class SaleTicketDemo1 { public static void main(String[] args) { //并发,多个线程操作同一个资源类,把资源类丢入线程 Ticket ticket=new Ticket(); //Runnable原创 2020-12-31 14:33:18 · 3001 阅读 · 3 评论 -
Java并发编程-线程安全基础
1.线程安全问题2.1、为什么这个是重点? 以后在开发中,我们的项目都是运行在服务器当中,而服务器已经将线程的定义,线程对象的创建,线程的启动等,都已经实现完了。这些代码我们都不需要编写。 最重要的是:你要知道,你编写的程序需要放到一个多线程的环境下运行,你更需要关注的是这些数据在多线程并发的环境下是否是安全的。(重点:*****)2.2、什么时候数据在多线程并发的环境下会存在安全问题呢? 三个条件: 条件1:多线程并发。 条件2:有共享数据。 条件3:共享数据有修改的行为。原创 2020-12-27 22:10:02 · 2651 阅读 · 2 评论 -
Java并发编程-多线程基础
1.多线程概述1、什么是进程?什么是线程? 进程是一个应用程序(1个进程是一个软件)。 线程是一个进程中的执行场景/执行单元。 一个进程可以启动多个线程。2、对于java程序来说,当在DOS命令窗口中输入:java HelloWorld 回车之后。 会先启动JVM,而JVM就是一个进程。 JVM再启动一个主线程调用main方法。 同时再启动一个垃圾回收线程负责看护,回收垃圾。 最起码,现在的java程序中至少有两个线程并发, 一个是垃圾回收线程,一个是执行main方法的主原创 2020-12-27 19:22:04 · 3650 阅读 · 9 评论