并发编程
2021-02-23 14:22:29 0 举报
AI智能生成
登录查看完整内容
为你推荐
查看更多
java面试_并发
作者其他创作
大纲/内容
内存模型
多线程情况下,每个线程有自己的工作内存,每开一个线程,会从主内存中读取一遍变量,缓存到工作内存,除非对变量修改,否则不会修改缓存中的数据;当数据被修改后,数据会刷新到主内存;
线程
ThreadLocal
使用场景
数据库事务:给个每个线程(请求)一个connection,这样我们关闭自动提交事务,就可以实现手动提交事务了设置请求id等
原理
每个Thread对象都维护了一个ThreadLocalMap,里面存的就是当前线程个性化的数据,实现数据隔离的思想;那ThreadLocal相当于在一个工具包,可以对外提供每个Thread中的ThreadLocalMap中存储的东西,ThreadLocalMap也是Map,key值存的是ThreadLocal对象的引用,我们在使用ThreadLocal的时候,一般只new一个static的ThreadLocal,所以,多线程情况下,每个线程的ThreadLocalMap中key都一样,都是ThreadLocal的引用,value就属于个性化的东西了,原理大概就是这样。
理解
两大优点:相当于一个自己的变量云存储1、传递数据,保存每个线程保存的数据,需要的时候可以直接获取,避免了参数传递的麻烦2、线程隔离:每个线程中中绑定的数据相互隔离,
弱引用和内存泄漏
概念:内存溢出:内存的空间不够了内存泄漏:堆内存的空间因为某种原因无法释放,最终导致内存溢出弱引用:垃圾回收发现弱引用的对象,不管空间是否足够,都会回收空间
hash冲突
线性探测法Entry[] table可以看成一个环形数组
线程池
tomcat线程池
springboot线程池
多线程同步有哪些呢
synchronizedlockwait/notifyawait/signalAllcountDownLatchcyclibairsamephore
juc
AQS
CountDownLatch
场景:计数器。主线程等(.await())所有子线程把总数消耗完成(.countDown())后,主线程开始继续走
CyclicBarrier
场景:运动员上跑道,等所有人都准备好(.await())好后,裁判发令(重启一个线程干一件事情)
Samephore
场景:停车位上停车,
并发编程
要保证
原子性可见性有序性
synchronized
原子性
悲观锁,同一时间只有一个线程在执行共享资源,能够保证原子性
可见性
加锁前,清空工作内存中的共享变量的值,从主内存中冲洗取值;释放锁前,将工作内存中的数据刷新到主内存
有序性
单线程,不会因为指令重排导致出现问题
加锁原理
为什么叫重量级锁呢加锁的时候,会调用操作系统,相当于同步在操作系统完成,导致操作系统内核态和用户态来回切换,导致速度变慢
子主题
volatile
不保证
可见性原理:lock addl指令+缓存一致性协议 + 内存屏障;在原来写操作的基础上,加了volatile关键字的变量,在写的时候,jvm会给cpu加一个lock指令,cpu在写完数据之后,会立即将数据刷新到主内存,同时因为缓存一致性,其他线程会嗅探自己的变量有没有被修改,如果被修改,会将数据设置为无效,这样在读数据的时候,就会从主内存中加载最新的数据,保证了数据的可见性
有序性原理:内存屏障写数据:storestore + 修改数据 +storeload +flush到祝内存读数据: 从主内存读取数据(如果失效) + loadload + 读数据 + loadstore
lock
为什么叫轻量级锁呢同步在jvm级别就去解决
https://zhuanlan.zhihu.com/p/80929454?from_voters_page=true
reentrantlock呢,首先他是为了解决线程同步问题,之前有synchronized,但是这个synchronized1.6之前属于重量级锁,原因是他涉及内核态和用户态的来回切换,所以,Doug le 想,我们可以在java层就解决线程的同步的问题,不再去麻烦系统,于是有了reentrantlock。那aqs/lock无非围绕着 自旋+park+cas实现的;
源码
重入: 相同的线程进来后,如果当前的status!=0,那么还会判断这个线程是不是重新进来的,如果是则把status+1返回,表示重入了一次如果锁被占用,并且当前线程不是重入,返回false,表示没上锁tryAcquire()
入队:队列里面的队头永远是空,空是指里面的thread为空
0 条评论
回复 删除
下一页