![](https://img-blog.csdnimg.cn/20210112103420121.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
Java并发编程
文章平均质量分 63
学习Java并发编程的笔记
Lavender-csdn
这个作者很懒,什么都没留下…
展开
-
JUC工具类
Semaphore信号量,用来限制能同时访问共享资源的线程上限Semaphore应用使用Semaphore限流,在访问高峰期时,让请求线程阻塞,高峰期过去再释放许可,当然它只适合限制单机线程数量,并且仅仅是限制线程数,而不是限制资源数 用Semaphore实现简单连接池,性能和可读性显然更好Semaphore原理加锁(acquire)解锁(release)流程Semaphore有点像一个停车场,permits就好像停车位数量,当线程获得了permits就像是获得了停车位,然后停车场显原创 2021-02-20 21:11:16 · 323 阅读 · 0 评论 -
尽量搞懂ReentrantLock原理
ReentrantLock原理在Java5.0之前,在协调对共享对象的访问时可以使用的机制只有synchronized和volatile,Java5.0增加了一种新机制:ReentrantLock,与之前提到的机制相反,ReentrantLock并不是一种替代内置加锁的方法,而是当内置加锁机制不适用的时候,作为一种可选择的高级功能。ReentrantLock实现了Lock接口,Lock提供了一种无条件的、可轮询的、定时的以及可中断的锁获取操作,所有加锁和解锁的方法都是显示的。ReentrantL原创 2021-02-20 11:36:41 · 181 阅读 · 0 评论 -
volatile到底是个什么鬼--详解
问题:退不出的循环先看一个现象,main线程对run变量的修改对于t线程不可见,导致了t线程无法停止static boolean run=true;public static void main(String[] args) throws InterruptedException{ Thread t=new Thread(()->{ while(run){ //... } }); t.start();原创 2021-02-19 21:47:24 · 134 阅读 · 0 评论 -
线程池
ThreadPoolExecutor线程池状态ThreadPoolExecutor使用int的高3位来表示线程池状态,低29位表示线程数量构造方法public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, int keepAliveTime, TimeUni.原创 2021-02-19 20:48:49 · 98 阅读 · 0 评论 -
wait¬ify原理
原理之wait/notifyOwner线程发现条件不满足,调用wait方法,即可以进入WaitSet变为WAITING状态 BLOCKED和WAITING的线程都处于阻塞状态,不占用CPU时间片 BLOCKED线程会在Owner线程释放锁时唤醒 WAITING线程会在Owner线程调用notify或者notifyAll时唤醒,但是唤醒后并不意味着立刻获得锁,仍然需要进入EntryList重新竞争API介绍obj.wait()让进入object监视器的线程到waitSet等待 obj.n原创 2021-02-18 14:43:49 · 138 阅读 · 0 评论 -
synchronized锁优化
轻量级锁轻量级锁应用原理:如果一个对象虽然有多线程访问,但多线程访问的时间是错开的,那么可以使用轻量级锁来优化轻量级锁对使用者是透明的,即语法还是synchronized创建锁记录对象,每个线程的栈帧都会包含一个锁记录结构,内部可以存储锁定对象的Mark Word让锁记录中Object reference指向锁对象,并尝试使用cas替换Object的Mark Word,将Mark Word的值存入锁记录如果cas替换成功,对象头中存储了锁记录地址和状态00,表示由该线程给对象加锁原创 2021-02-18 14:17:54 · 127 阅读 · 0 评论 -
Monitor概念
Java对象头以32位虚拟机为例普通对象数组对象其中Mark Word结构为MonitorMonitor被翻译为监视器或者管程每个Java对象都可以关联一个Monitor对象,如果使用synchronized给对象上锁(重量级)之后,该对象头的Mark Word中就被设置指向Monitor的指针Monitor结构如下刚开始Monitor中Owner为null 当Thread-2执行synchronized(obj)就会将Monitor的所有者Owner置原创 2021-02-18 13:13:09 · 381 阅读 · 0 评论 -
变量的线程安全分析
成员变量和静态变量是否线程安全?如果没有共享,则线程安全 如果它们共享了,根据它们的状态是否能够改变,又分两种情况如果只有读操作,则线程安全 如果有读写操作,则这段代码是临界区,需要考虑线程安全局部变量是否线程安全?局部变量是线程安全的 但是局部变量引用的对象则未必如果该对象没有逃离方法的作用访问,它是线程安全的 如果该对象逃离方法的作用范围,则需要考虑线程安全局部变量线程安全分析:public static void test1(){ int i=10; i.原创 2021-02-18 12:52:51 · 111 阅读 · 1 评论 -
synchronized解决线程安全问题
应用之互斥为了避免临界区的竞态条件发生,有多种手段可以达到目的。阻塞式的解决方案:synchronized、Lock非阻塞式的解决方案:原子变量synchronized:俗称的对象锁,它采用互斥的方式让同一时刻至多只有一个线程拥有对象锁,其它线程再想获取这个对象锁的时候就会阻塞住,这样就能保证拥有锁的线程可以安全的执行临界区内的代码,不用担心线程上下文切换。注意:虽然Java中互斥和同步都可以使用synchronized关键字来完成,但是它们是有区别的:互斥是保证临界区的竞态条件发生原创 2021-02-18 11:42:20 · 700 阅读 · 1 评论 -
线程安全问题
Java体现两个线程对初始值为0的静态变量一个做自增,一个做自减,各做5000次,结果是0吗?问题分析:以上的结果可能是正数、负数、零,为什么呢?因为Java中对静态变量的自增、自减并不是原子操作,要彻底理解,必须从字节码来进行分析。例如对i++而言(i为静态变量),实际上会产生如下的JVM字节码指令:而对应i--也是类似:而Java的内存模型如下,完成静态变量的自增、自减需要在主存和工作内存中进行数据交换:如果是单线程执行以上代码是顺序执行没有问题:...原创 2021-02-18 10:46:46 · 170 阅读 · 1 评论 -
线程的状态
五种状态这是从操作系统层面来描述的初始状态: 仅仅是在语言层面创建了线程对象,还没有与操作系统线程相关联可运行状态:指该线程已经被创建(与操作系统线程关联),可以由cpu调度执行运行状态:指获取了cpu时间片运行中的状态当cpu时间片 用完,会从运行状态转换至可运行状态,会导致线程的上下文切换阻塞状态如果调用了阻塞API,如BIO读写文件,这个时候线程实际不会用到cpu,会导致线程上下文切换,进入阻塞状态; 等BIO操作完毕,会由操作系统唤醒阻塞的线程,转换成可运行状态;原创 2021-02-18 10:25:33 · 97 阅读 · 0 评论 -
Java线程中常见方法
常见方法start与run直接调用run是在主线程中执行了run方法,没有启动新的线程使用start是启动新的线程,通过新的线程间接执行run中的代码sleep与yield1、调用sleep会让当前线程从Running进入Timed Waiting状态(阻塞)2、其他线程可以使用interrupt方法打断正在睡眠的线程,这个时候sleep方法会抛出InterruptedException3、睡眠结束后的线程未必会立刻得到执行4、建立使用TimeUnit的sleep代原创 2021-02-17 22:32:13 · 152 阅读 · 0 评论 -
Java线程运行原理
栈与栈帧我们都知道JVM由堆、栈、方法区所组成,其中栈内存是给谁用的呢?其实就是线程,每个线程启动后,虚拟机就会为其分配一块内存1、每个栈由多个栈帧组成,对应着每次方法调用时所占用的内存2、每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法线程上下文切换因为一下一些原因导致cpu不再执行当前线程,转而执行另外一个线程的代码1、线程的CPU时间片用完2、垃圾回收3、有更高优先级的线程需要运行4、线程自己调用了sleep、yield、wait、join、park、syn原创 2021-02-17 21:53:31 · 266 阅读 · 4 评论 -
Java线程的创建与运行
创建和运行线程方法一,直接使用ThreadThread t = new Thread(){ public void run(){ //线程需要执行的代码 }};//启动线程t.start()方法二,使用Runnable配合Thread把线程和任务需要执行的代码分开Thread代表线程Runnable中包括可运行的任务(线程需要执行的代码)方法三,FutureTask配合ThreadFutureTask能够...原创 2021-02-17 21:33:50 · 154 阅读 · 0 评论 -
进程与线程
进程程序由指令和数据组成,但是这些指令要运行,数据要读写,就必须将指令加载至CPU,数据加载到内存,在指令运行过程中还需要用到磁盘、网络设备。进程就是用来加载指令、管理内存、管理IO的。当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。进程就可以视为程序的一个实例。大部分程序可以同时运行多个实例进程线程一个进程之内可以分为一到多个线程一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给CPU执行java中,线程作为最小调度单位,进程作为资源分原创 2021-02-17 21:07:14 · 92 阅读 · 0 评论