JUC
文章平均质量分 74
Fairy要carry
欲戴其冠,必承其重
展开
-
线程池再思考(业务学习)
Java中线程池的核心实现类是,可以通过该类地构造方法来构造一个线程池,我们先来看下ThreadPoolExecutor的整个继承体系我们可以通过去构造一个线程池**Executor接口:**提供了将任务的执行和线程的创建以及使用解耦开来的抽象ExecutorService接口继承了Executor接口,在Executor的基础上,增加了一些关于管理线程池本身的一些方法,比如查看任务的状态、stop/terminal线程池、获取线程池的状态等等。根据不同的线程池,设置名称,方便管理线程。原创 2024-02-18 21:33:21 · 811 阅读 · 0 评论 -
在实际业务代码中CompletableFuture对任务的处理
是 Java 8 中引入的一个类,用于实现异步编程并发任务的组合和处理。它提供了丰富的方法来处理异步计算的结果、任务的完成状态、异常处理等,使得编写非阻塞式、高效率的并发代码变得更加简单和灵活1异步计算和结果获取: 可以通过、CompletableFuture.runAsync() 等方法创建异步任务,并在后台线程中执行。通过get()方法可以获取异步计算的结果,如果计算还未完成,则会阻塞当前线程。// 异步执行任务return 42;});// 获取异步计算的结果,会阻塞当前线程2。原创 2024-02-18 10:25:37 · 838 阅读 · 0 评论 -
Synchronized重型锁导致用户态与内核态之间的切换
Synchronized重型锁导致用户态与内核态之间的切换用户态与内核态切换详解原创 2023-02-10 11:24:44 · 290 阅读 · 0 评论 -
利用AtomicInteger完成一个可重入锁(含阻塞队列)
【代码】利用AtomicInteger完成一个可重入锁(含阻塞队列)原创 2022-09-23 13:56:19 · 239 阅读 · 0 评论 -
ThreadLocal
前置: ThreadLocal——线程本地存储。也就是线程本地变量的管理者,一般用于实现线程隔离(数据隔离),在线程中使用它存储数据,仅在当前线程访问使用其实,它仅仅是一个管理者,真正存储数据的不是它,而是一个叫做ThreadLocalMap的对象,每个线程都有一个自己的TreadLocalMap对象(在Thread中对象名为:threadLocals或者inheritableThreadLocals)。场景:比如JDBC,我们每个线程进行数据库操作,连接都有自己独有的,而不会出现a连接到b上面这里我们会体原创 2022-07-02 12:11:03 · 168 阅读 · 0 评论 -
互斥和同步区别
区别:互斥:是指三部在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。同步:是指散步在不同进程之间的若干程序片断,它们的运行必须严格按照规定的 某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。 联系:同步是一种更为复杂的互斥,而互斥是一种特殊的同步。也就是说互斥是两个线程之间不可以同时运行,他们会相互排斥,必须等待一个线程运行完毕,另一个才能运行,而同步也是不能同时运行,但他是必须要安照某种次序转载 2022-06-01 10:50:37 · 3607 阅读 · 1 评论 -
ConcurrentHashMap
与HashMap类似,由Segment,HashEntry组成,是数组+链表构成;Segment是ConcurrentHashMap中的一个内部类:原理:ConcurrentHashMap采用了分段锁技术,其中Segment(可以理解为一小段数组,里面含有n个HashEntry)继承ReentrantLock,但是put和get操作都会被同步处理——>每当一个线程占用锁访问Segment时,不会影响其他的Segment(可以理解为:有多把锁,一把锁锁住的临界区不会影响其他的地方)vo.原创 2022-05-04 01:19:41 · 1674 阅读 · 2 评论 -
Countdownlatch执行任务+Future
概念:CountDownLatch是一个同步工具类,也就是说它运行一个或多个线程一直等待;这种等待类似于我们之前学的join,与之不同的是:join:可以具体到具体线程,只要该线程执行完毕,后面代码就结束等待;CountDownLatch:可以一直等待;比如:主线程需要所有组件加载完毕才会启动,类似于boot的启动;...原创 2022-05-02 02:13:40 · 2766 阅读 · 0 评论 -
stampedlock
对比与读写锁,它采用了一个验戳的操作,减少了锁的使用;缺点:不支持条件变量与可重入;原创 2022-04-30 23:25:03 · 113 阅读 · 0 评论 -
ReentrantWriteLock原理
前言众所周知,ReentrantReadWriteLock是读写锁,它拥有独占锁和共享锁两种模型。如果是读操作:上共享锁,因为是可以同时访问的;而如果是写操作:上独占锁,写写或者读写都得上锁,等它完成释放资源后才能其他的访问;其实ReentrantLock与之一样,ReentrantWriteLock是一把锁写锁的获取其实会尝试获取三次,这个for循环里会判断两次,如果还是没有获取到锁,那么就会被park进入阻塞;public void lock() { .原创 2022-04-29 15:38:53 · 246 阅读 · 0 评论 -
ReentrantWriteLock
特点:读读并发,读写,写写互斥;不支持可重入 ,会阻塞比如,你有多个线程在读取内容,另一个线程给他升级版本,这样对读取肯定不友好——>这就是读写锁的重入;(但是这套重入只针对于读的时候写)如果是写的时候读那就没关系了(边更新边读取内容)——>也就是说我们可以在写锁释放前获得读锁;——>可以理解为降级降级为读锁的好处:可以让其他线程都读取缓存数据,不被其他线程写烦扰,然后写锁unlock防止其他线程干扰数据,造成读影响;案例:缓存原创 2022-04-26 22:58:20 · 760 阅读 · 0 评论 -
ReentrantLock的条件变量await+signal+公平锁原理
目录公平锁实现原理:条件变量-await条件变量之唤醒-signal公平锁实现原理:它会判断你的AQS队列中是否有前驱节点,没有才会去竞争;判断方法hasQueuedPredecessors():1.根节点head后是否有第二个节点 2.拥有者是否是当前线程;条件变量-await public final void await() throws InterruptedException { if (Thread.in...原创 2022-04-25 00:39:18 · 367 阅读 · 0 评论 -
ReentrantLock的获取锁资源以及释放锁资源+可重入原理分析
/** * Creates an instance of {@code ReentrantLock}. * This is equivalent to using {@code ReentrantLock(false)}. */ public ReentrantLock() { sync = new NonfairSync(); } /** * Creates an instance of {@code Reentr...原创 2022-04-24 17:00:44 · 1125 阅读 · 0 评论 -
aqs的学习
目录概述:需要由子类实现的保护方法其他方法锁和同步器的区别自定义锁-独占锁AQS小结概述:通过继承它来实现父类的功能获取锁:阻塞和获取资源用的是park和unpark;释放锁:判断是否有锁资源:AbstractQueuedSynchronizer公有方法(AQS)1.acquire:独占式获取同步状态;2.release:独占式释放同步状态;3.acquireShared(int arg):共享式获取...原创 2022-04-23 18:28:00 · 348 阅读 · 0 评论 -
Tomcat线程池和ForkJoinPool线程池
这里线程分了三个部分:Acceptor:负责接收Socket连接;Poller:监听Socket连接是否有IO读写操作——>采用了多路复用的思路,所以线程数只需要1就可以检测哪些连接具有IO操作;线程池中的Worker:对任务进行执行,读写数据;Tomcat线程池与ThreadPoolExecutor的区别:如果总线程数达到了maximumPoolSize——>不会抛出异常;它会再次将任务放入队列,如果还是失败,就会抛出RejectedExecutionExcepti..原创 2022-04-23 14:59:41 · 868 阅读 · 0 评论 -
线程池状态+ThreadPoolExecutor
int中有32位,高3位表示线程状态,低29位表示线程数量;SHUTDOWN:新任务不接受,以前的还是照常执行stop状态:会利用Interrupt方法打断任务,就算你是正在执行的任务,也会被抛弃;TIDYING状态:线程全部执行完毕了,马上会进入终结状态;TERMINDATED:终结状态;我们会将这些信息(线程状态+线程数量)储存到一个原子变量中;——>目的:减少一次CAS操作;ThreadPoolExecutor的构造方法corePoolSi...原创 2022-04-22 00:59:45 · 1556 阅读 · 0 评论 -
手写线程池
package com.example.juc.ThreadPool;import lombok.extern.slf4j.Slf4j;import java.util.ArrayDeque;import java.util.Deque;import java.util.HashSet;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.Condition;import java.util.conc.原创 2022-04-20 17:41:23 · 270 阅读 · 0 评论 -
保护性拷贝+亨元模式
不可变对象线程安全可变的一个线程安全使用:package com.example.juc.Automic.Date;import lombok.extern.slf4j.Slf4j;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.concurrent.locks.ReentrantLock;/** * @author diao 2022/4/19 */...原创 2022-04-19 19:54:43 · 337 阅读 · 0 评论 -
final
理解final首先,我们知道的是,final修饰的变量都是不能改变的,也就是说其他线程都修改不了;特点:1、不可继承,不可重写;2、final修饰而局部参数,都是需要初始化的;作用:它会在赋值之后加上一个写屏障——>1.有序性:保障写屏障之前的操作不会重排序到写屏障之后;2.读可见:写屏障之前的所有修改、赋值操作都会同步到主存中;体现出了只读不能改;举个例子:如果没有final,默认是0,那么其他线程就会读取到a为0的情况,但是你加上final,就不会出现,没有...原创 2022-04-19 19:22:11 · 97 阅读 · 0 评论 -
LongAdd
为什么要用LongAddr?之前我们所学的AtomicLong本质是通过CAS方法来保证原子性的,但是如果多线程下,一个线程t1改变了共享资源状态,而另一线程t2因为资源改变,导致CAS失败,那么t2就会不断去自旋进行多次尝试——>导致性能底下;场景:在高并发情况下,大量线程去操作同一共享资源,那么势必会造成大多数线程CAS失败,然后就会陷入自旋状态,那么就会浪费CPU资源,并且降低了并发性(:一时间段发生事件的次数);解决:我们试想,如果将一个变量拆分为多个变量,是不是..原创 2022-04-19 09:28:16 · 305 阅读 · 0 评论 -
共享模型无锁并发
目录CAS无锁实现互斥行为为什么要用AtomicIntegerdebug代码分析为什么无锁效率高?CAS特点CAS无锁实现互斥行为package com.example.juc.unsafe;import java.util.ArrayList;import java.util.List;import java.util.concurrent.atomic.AtomicInteger;/** * @author diao 2022/4/15 ...原创 2022-04-17 13:27:03 · 318 阅读 · 0 评论 -
阶段总结(可见性+有序性+犹豫模式+终止模式)
解决可见性问题1.synchronized修饰变量因为synchronized可以保持互斥——>确保共享变量被当前锁修改之后,才会被其他线程获取到,读取的直接就是主内存;而一个变量被一个线程t1读取,然后另一个线程t2修改变量,那么t1再读取这个变量就会出问题;2.volatile修饰的变量也不会存在可见性问题当一个变量被volatile修饰,那么读取他的时候,会从主内村读取,而不是工作内存;3.final修饰的变量也不会存在;因为final在编译时期就确定了,赋值...原创 2022-04-15 18:00:00 · 317 阅读 · 0 评论 -
可见性与有序性和原子性01
实例:不可见性package com.example.juc.JMM;import lombok.extern.slf4j.Slf4j;import static java.lang.Thread.sleep;/** * @author diao 2022/4/13 */@Slf4j(topic = "c.Test01")public class Test01 { static boolean run=true; public static void mai...原创 2022-04-15 00:53:27 · 694 阅读 · 1 评论 -
设计模式-一些输出方式demo
例题1:交替输出今天突然发现notifyAll()能唤醒当前线程(也就是当前线程也能自抢)package com.example.juc.ReengtrantLock.Alternate;import lombok.extern.slf4j.Slf4j;/** * @author diao 2022/4/13 *///一个交替输出@Slf4j(topic = "c.Test01")public class Test01 { public static void ma.原创 2022-04-13 19:41:55 · 557 阅读 · 1 评论 -
多把锁+ReentrantLock+活锁+死锁
多把锁并发度:同一个时间节点上,可能与服务端进行交互的用户个数;如何增强并发度:首先明确,并发度增强无非就是交互个数在一个时间点上变多——>那么我们可以设置多把锁。目的就是同一时间上交互变多;例子:package com.example.juc.Multi;import lombok.extern.slf4j.Slf4j;/** * @author diao 2022/4/10 */@Slf4j(topic = "c.TestMultiLock")publ.原创 2022-04-11 00:29:13 · 843 阅读 · 1 评论 -
线程状态切换(后续继续补)
new:创建线程RUNNABLE:线程执行,start();wait ()——>WAITING等待状态,区别:会释放锁资源;sleep()——>也会进入等待状态;RUNNABLE->WAITTING: 1.调用join方法的线程;2.调用Interrupt()方法,让当前线程变成wiatting状态;3.park():LockSupport.park():当前线程由RUNNABLE->WAITTING;join方法的底层就是wait实现的:在主线程区域中调用...原创 2022-04-10 19:22:05 · 177 阅读 · 0 评论 -
Park和unPark方法
目录介绍原理例子介绍简而言之:1.park和unpark是以线程为单位精确阻塞和唤醒线程的;2.阻塞和唤醒的先后执行顺序可以不一样;原理park:counter相当于干粮(只有0或1两种状态),Parker相当于背包,_cond:相当于帐篷——>当干粮counter不够时,就会进入_cond帐篷;——>也就是线程进入帐篷中阻塞而unPark:相当于补充干粮,但是不会溢出,所以说我们可以先执行unPark,再执行park...原创 2022-04-10 11:05:30 · 1444 阅读 · 0 评论 -
设计模式-保护性暂停和生产者消费者
如果是一个线程将一个结果传到另外一个线程——>用GuardedObject关联彼此即可;如果是多个结果,源源不断的传输,就需要用到消息队列——>进行一个削峰的作用(就是有一个中间储存你的结果,慢慢将一部分结果传输,而不是一下传输全部);案例:保护性暂停无保护情况:package com.example.juc.Gurard;import lombok.extern.slf4j.Slf4j;import java.io.IOException;import j...原创 2022-04-10 09:25:07 · 214 阅读 · 0 评论 -
wait和notify,sleep
举个例子:就跟你去酒店一样在大堂找老总解决排队问题,你一直在大堂找老总就会影响其他客人,所以酒店给你安排到贵宾室等待,直到老总来了,在大堂,事情得到解决,重新在酒店外排队候单;WAITTING和BLOCKED区别waitting:是线程已经获取了锁,但又放弃了锁(有些问题需要解决)——>进入了waitset(在Monitor中)进行等待;——>唤醒:Owner调用notify()或notifyAll()方法进行唤醒——>唤醒后线程继续进入EntryList进行等待;.原创 2022-04-09 14:05:55 · 775 阅读 · 0 评论 -
偏向锁+轻量型锁+重量型锁
使用时间错开——用轻量级锁(挂书包)如果有一个线程很长时间都不在使用——>另一个线程每次使用都要挂书包比较麻烦——>可以采用偏向锁的方式,没人竞争,就升级成偏向锁,否则再回到轻量级锁;再次升级,当一个线程偏向锁达到20阈值时,然后该线程休息,另外线程来竞争,导致批量撤销该类对象的偏向锁,——>使用一种批量重刻名的方法:擦名字刻名字操作;轻量级锁场景:cas成功:lock record:线程中的锁记录会与对象中对象头中的markword进行交换,导致:状态从.原创 2022-04-08 21:50:06 · 393 阅读 · 0 评论 -
Monitor初次理解
目录对象头Monitor什么时候执行下一个线程呢?Monitor字节码总结:对象头每个对象都是有对象头的由Mark word+Klass word组成Mark word:里面描述对象状态:什么类型的锁呀或者是垃圾回收GC之类的,还有存活(分代)年龄、hashcode啥的01:没有任何关联;10:有关联;——>mark word就会储存指向xxx的指针Klass Word:一个指针,指向了对象所属的类,可以通过这个指针—...原创 2022-04-07 22:09:56 · 612 阅读 · 0 评论 -
线程安全问题
线程安全问题介绍正数情况例子:例如:1.首先拿到全局静态变量a,在第一个线程中我们对其进行加法,但是值还没有写入给静态变量,(只是记住了值要为1),然后时间片分配的时间到了,线程上下文2.切换到第二个线程,第二个线程此时读取全局变量值就为之前没有+的时候的值,这个线程分配的CPU较多,把最后的值写入给全局静态变量a了(假设是减法-10),然后3.再回到线程1,读取之前记住的值,结果为1而不是-9;出现问题根源:多个线程对共享资源进行读写操作时,指令发生了交错——>出问题...原创 2022-04-06 21:29:19 · 454 阅读 · 0 评论 -
补充:一些常见方法以及第一阶段总结
目录pork与Interrupted()方法练习2守护线程线程状态:例子:洗茶壶(多线程处理问题)小结:pork与Interrupted()方法pork:终止线程,下面的不再运行,其实就是根据线程状态来的,如果为true就可以往下执行Thread.interrupted():将线程状态设置为反思路:我们先进行对线程t1的终止,之后主线程运行使用Interrupt方法打断线程,导致可以继续t1线程的运行,此时状态为true,输出repark后,我们利用Int..原创 2022-04-01 19:20:37 · 191 阅读 · 0 评论 -
JUC-02线程创建
有@FunctionalInterface说明该方法可以用lambda来简化写法有Runnable时线程中的任务,如果有Runnable,也就是target!=null,就会执行runnbale中的run方法,好处:1.Runnable更容易与线程池等高级API配合2.而且让任务类摆脱了Thread继承体系,更加灵活,组合优于配合(9条消息) java-组合优于继承_简洁是智慧的灵魂的博客-CSDN博客_java 组合优于继承package JUC.线程;...原创 2022-04-01 13:23:46 · 732 阅读 · 0 评论 -
JUC-01
目录线程与进程的区别:并发:并行:运行效率异步调用:单核多核处理多线程单线程性能例子:线程与进程的区别:进程:用来加载指令(操作)至CPU中,读取数据进内存的;相当于是管理数据与指令,IO的;当一个程序被执行时,进程就会被开启,指令被加载到CPU读取操作(后面会给指令分配时间片),将磁盘中的数据加载到内存中;线程:具体是执行指令的,一个线程就是一个指令流,你可以理解为进程是储存线程的,一个进程里面可以有多个线程,进程会给线程分配资源,以此给...原创 2022-03-31 16:08:34 · 179 阅读 · 0 评论