并发编程(使用场景)面试题及原理
1. 线程池使用场景1.1 es数据批量导入
https://i-blog.csdnimg.cn/direct/a7b1750752e24a74b3ee87ee239abfc5.png
1.1.1 CountDownLatch
CountDownLatch(闭锁/倒计时锁)用来举行线程同步协作,等待所有线程完成倒计时(一个或者多个线程,等待其他多个线程完成某件事情之后才能执行)
[*]其中构造参数用来初始化等待计数值
[*]await()用来等待计数归零
[*]countDown()用来让计数减
https://i-blog.csdnimg.cn/direct/4ae0e898d4794d50be3bf003c69d2539.png
1.1.2 数据汇总
在一个电商网站中,用户下单之后,必要查询数据,数据包含了三部分:订单信息、包含的商品、物流信息;这三块信息都在不同的微服务中举行实现的,我们怎样完成这个业务呢?
https://i-blog.csdnimg.cn/direct/6cee72f798934e3b8f1a29b85153bb71.png
在实际开发的过程中,难免必要调用多个接口来汇总数据,如果所有接口(或部分接口)的没有依靠关系,就可以使用线程池+future来提升性能
ex:报表汇总
https://i-blog.csdnimg.cn/direct/e4652fc517a449afa890e011e4da0d49.png
1.1.3 异步调用
为了避免下一级方法影响上一级方法(性能思量),可使用异步线程调用下一个方法(不必要下一级方法返回值),可以提升方法响应时间
https://i-blog.csdnimg.cn/direct/b913f6880e1f446eb7da0f0c7d9f43c5.png
2. 控制方法并发访问线程的数目
Semaphore使用步调
[*]创建Semaphore对象,可以给一个容量
[*]semaphore.acquire():请求一个信号量,这时候的信号量个数-1(一旦没有可使用的信号量,也即信号量个数变为负数时,再次请求的时候就会壅闭,直到其他线程释放了信号量)
[*]semaphore.release():释放一个信号量,此时信号量个数+1
https://i-blog.csdnimg.cn/direct/12a0e4313cd7495bb4b23282b290de89.png
3. 谈谈你对ThreadLocal的理解
ThreadLocal是多线程中对于办理线程安全的一个操作类,它会为每个线程都分配一个独立的线程副本从而办理了变量并发访问辩论的问题。ThreadLocal 同时实现了线程内的资源共享
案例:使用JDBC操作数据库时,会将每一个线程的Connection放入各自的ThreadLocal中,从而保证每个线程都在各自的Connection 上举行数据库的操作,避免A线程关闭了B线程的毗连。
https://i-blog.csdnimg.cn/direct/81844e3019344f939b89c6e69253ae1d.png
3.1 ThreadLocal基本使用
实现【资源对象】的线程隔离,让每个线程各用各的【资源对象】,避免争用引发的线程安全问题
[*]set(value): 设置值
[*]get() :获取值
[*]remove():清除值
https://i-blog.csdnimg.cn/direct/88fb353128594ce08aee1e91a2b857eb.png
3.2 的实现原理、源码剖析
ThreadLocal本质来说就是一个线程内部存储类,从而让多个线程只操作自己内部的值,从而实现线程数据隔离,每个线程内有一个 ThreadLocalMap 类型的成员变量,用来存储资源对象
https://i-blog.csdnimg.cn/direct/23665b4f6ccd4028a3dc32938af7530a.png
3.2.1 set方法
调用set 方法,就是以 ThreadLocal自己作为 key,资源对象作为 value,放入当前线程的 ThreadLocalMap 聚集中
3.2.2 get方法/remove方法
调用get方https://i-blog.csdnimg.cn/direct/64c70ade48a74a7292e2b0d25480f320.png
法,就是以 ThreadLocal自己作为key,到当前线程中查找关联的资源值
调用 remove 方法,就是以ThreadLocal 自己作为 key,移除当前线程关联的资源值
https://i-blog.csdnimg.cn/direct/bc98780650df41bcbd4e3f75644dbb09.png
3.2.3 内存泄露
Java对象中的四种引用类型:强引用、软引用、弱引用、虚引用
[*]强引用:最汐平凡的引用方式,表现一个对象处于有用且必须的状态,如果一个对象具有强引用,则GC并不会接纳它。即便堆中内存不足了,宁可出现OOM,也不会对其举行接纳
User user = new User();
[*]弱引用:表现一个对象处于大概有用且非必须的状态。在GC线程扫描内存地区时,一旦发现弱引用,就会接纳到弱引用相干联的对象。对于弱引用的接纳,无关内存地区是否足够,^一旦发现则会被接纳
User user = new User();
WeakReference weakReference = new WeakReference(user); 每一个Thread维护一个ThreadLocalMap,在ThreadLocalMap中的Entry对象继承了WeakReference。其中key为使用弱引用的ThreadLocal实例,value为线程变量的副本
https://i-blog.csdnimg.cn/direct/e905e4a9705f46b98b277d2ba8e7fd50.png
ThreadLocalMap中的key是弱引用,值为强引用;key 会被GC释放内存,关联value的内存并不会释放。建议主动 remove 释放 key,value
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]