转载自 java面试线程必备知识点,怼死面试官,从我做起

|--多线程一定好么?

cpu密集不好 io密集好

|--如何减少上下文切换:

无锁并发(数据id根据Hash分段)、CAS、最少线程

|--java线程避免死锁:

避免一个线程同时有多个锁

避免一个锁占用多个资源

lock.tryLock代替内部锁

内存屏障:限制命令操作顺序,有LoadLoad、LoadStore、LoadStore、StroreStreo四种屏障

缓冲行:cpu缓存最小储存单位

写命中:缓存有,直接写入缓存

缓存一致性:主存改变,其他缓存改变(read、load、use绑定)

顺序一致性:单个线程内执行结果一定是不变的(但依然有指令重排,只是结果不受影响的重排)

|--八个CPU原子命令:

lock、unlock、read、load、use、assign、store、write

|--volatile做的事:

1.lock前缀指令使缓存行立即写入内存(assign、store、write绑定)

2.其他cpu缓存无效

3.加入内存屏障

使用前景:不依赖于上次数据

使用案例:i++:tmp = i;tmp=tmp+1;i = tmp;

64位机器跑32位jvm,long和double:2段分2次计算,不加volatile会导致结果前32位是一个线程结果,后32位一个线程结果

|--synchronized

对象加锁,Monitor对象,monitorenter和monitorexit命令实现

锁升级

|--ReentrantLock 可重入锁

通过CVS等实现,比synchronized效率略高,有公平锁非公平锁

锁可多次进入,并把拥有数++

lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁

tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;

|--ReentrantReadWriteLock

read/write两把锁

写锁与ReetrantLock类似,只有写锁读锁都没被占用才获得锁

读锁拥有数是多个线程的,每个线程拥有数只能自己通过ThreadLocal记录

写锁结束降级读锁,避免可见性问题

|--Lock和synchronized区别

Lock是通过代码级实现,cvs

synchronized是通过jvm的monitor实现的

还多了 锁投票,定时锁等候和中断锁等候等特性

使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情

|--AQS(AbstractQueuedSynchronized)

有队列,有state、进入会先自旋再阻塞,默认非公平,队列唤醒了调用tryAcquire,不一定能获取锁

|--java对象头:

MarkWord 长度:32/64,存储hashCode或者锁信息

|--CAS unsafe.compareAndSwap(对象地址,原来值,要修改值)

unsafe是通过操作系统实现(CMPXCHG指令),如果失败返回false;

|--CAS使用:自旋锁、自适应自旋锁

|--锁的升级

偏向锁(markword指向所在线程,代价低,两个线程则停安全点撤销)->轻量级线程(markword置换到拥有者线程,线程对象互指。两个线程则b线程自旋等待)->重量级锁(syn、reeentrantLock)

比较:

偏向锁:  加锁解锁消耗极少,锁竞争的安全点带来消耗。      适用于一个线程

轻量级锁:响应快,自旋消耗cpu                                          追求响应时间,同步块非常快

重量级:                                                                              追求吞吐量,同步块执行时间长

|--处理器实现原子性策略:

LOCK#信号是一个线程独占共享内存(通过锁住主内存总线,之后优化成缓存锁)

缓存锁保证原子性

|--java原子实现:

锁和CAS

CAS局限性:ABA问题(过程无感知)、循环时间开销大、一次保证一个变量

|--内存模型(对底层抽象)

线程通信方式:

内存模型(共享内存)

消息传递(A复制到主内存,再从主内存写到B)

管道:输入流输出流(PipedReader,PipedWriter,PipedInputstream,PipedOutputStream)

内存模型:本地内存(共享变量副本、局部变量)、主内存(共享变量)

指令重排序:编译优化重排、并行重排、内存重排

|--final域重写规则

构造函数内,final写入与被构造的对象引用赋值不能重排序(obj=this会引发逃逸,例如此时别的线程调用obj.i,final的i变量还没初始化)

初次读含final域对象与随后读final区域不能重排

|--单例模式问题

实例化分为:1.开辟空间memory 2.初始化对象 3.设置instance指向memory。

指令重排可能是:1->3->2 , 若2还未执行,B线程认为instance非空,直接调用instance,导致错误

解决方案:1.volatile禁止重排序 2.匿名内部类(连自己加锁都不用,类自带实例化锁)

|--为什么使用多线程

1.多处理器发挥功效

2.更快相应,一个下订单带来一系列操作如何快速成功:线程派发,分任务执行

|--java优先级

不一定有用,主要是靠操作系统底层实现

|--interrupt

interrupt不会真的终止,只是一种协作机制

interrupt()将会设置该线程的中断状态位,即设置为true

使用Thread.currentThread().isInterrupted()方法(因为它将线程中断标示位设置为true后,不会立刻清除中断标示位,即不会将中断标设置为false)

thread.interrupted()(该方法调用后会将中断标示位清除,即重新设置为false)

一个线程处于了等待状态(thread.sleep、thread.join、thread.wait),则在线程在检查中断标示时如果发现中断标示为true,则会在这些阻塞方法调用处抛出InterruptedException异常,并且在抛出异常后立即将线程的中断标示位清除,即重新设置为false。抛出异常是为了线程从阻塞状态醒过来,并在结束线程前让程序员有足够的时间来处理中断请求。

锁的情况下不会被中断影响

|--阻塞状态与等待区别

阻塞是进锁里,等待是wait、sleep。sleep设置时间状态叫做超时等待状态

|--线程的应用

1.等待之后超时

while(结果未返回 && 时间未到)

wait();

2.线程池

要有队列,状态

Worker实现Runnable接口,循环从jobs队列取任务执行,获取不到就wait();

execute(Job job)时,唤醒jobs

3.基于线程池Web服务器

思路:开一个Socket服务,每次accept后,把这个一对一服务放封装成job类,放到jobs队列里

|--LockSupport

工具类,有park、unpark阻塞唤醒线程

|--Condition

相当于Lock中的wait和notify,区别是wait等待队列只能有一个,Condition可以有多个

Condition队列类似于AQS队列

每个Condition下面有一个等待await的等待队列

Lock.newCondition()获取condition

Lock.await(); = wait

Lock.singal();=notify

|--ConcurrentHashMap

问题:HashMap线程不安全导致Entry链表编程环,引发死循环。

HashTable效率低

解决:Segment包含HashEntry数组

Segment是一种可重入锁(ReentrantLock)

实现:segment数量是2的n次方,默认16

每一个segment的容量=每个segment里HashEntry*负载因子

如何放入数据:再散列确保数据分散后放入segment

get方法:不加锁,而是用volatile

1.8更新:没有了segment,横向用Node链表替代,Node被调用取时就synchronize加锁。当没Node底下链表超过8个,将加锁

|--ConcurrentLinkedQueue

非阻塞

入队:定位尾节点,不成功cvs重试(为了减少CVS,控制尾节点更新频率)

出队:

java面试线程必备知识点,怼死面试官,从我做起相关推荐

  1. python面试必考知识点_python编程面试中必考的知识点,数据类型全解,笔记超全面...

    原标题:python编程面试中必考的知识点,数据类型全解,笔记超全面 python作为一门高级编程语言,它的定位是优雅.明确和简单.阅读Python编写的代码感觉像在阅读英语一样,这让使用者可以专注于 ...

  2. java面试必备小知识_Java面试应该准备的知识点系列一

    当然,我是想换个平台,换个方向,想清楚为什么要跳槽,如果真的要跳槽,想要拿到一个理想的offer,除了运气,基本功也要足够的扎实,希望下面的面试经验能给你们能够提供一些帮助. 项目经验 面试官在一开始 ...

  3. 互联网java工程师面试突击第三季知识点总结

    目录 Java集合包 01. HashMap的底层数据结构是什么? 02. JDK1.8中对hash算法和寻址算法是如何优化的? 03.HashMap是如何解决hash碰撞问题的? 04.说说Hash ...

  4. Java 如何线程间通信,面试被问哭。。。

    Java 如何线程间通信,曾经小编面试被问哭的一道题.. 正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及 ...

  5. 大专java方向校招面试找工作知识点技术栈以及实习感受分享-简历分享

    大专java方向校招面试找工作知识点技术栈以及实习感受分享 专科生的Java学习以及校招面试 先说一下我的编程历程 开始求职之路 第一次求职 网上海投 第二次面试 第三次面试 学校招聘会 第四次面试 ...

  6. 面向面试的Java后端必会知识点概述及面经

    博主本人是非科班硕士,今年三四月份时开始刷题准备找工作.实习加秋招投了很多大厂&中厂,但是有小一半都没能进面试.秋招最终拿到了OPPO提前批测开.腾讯音乐后台开发.阿里云Java开发的offe ...

  7. java面试需要掌握知识点

    重点知识 由于我面试的JAVA开发工程师,针对于JAVA,需要理解的重点内容有: JVM内存管理机制和垃圾回收机制(基本每次面试都会问,一定要搞得透彻) JVM内存调优(了解是怎么回事,一般做项目过程 ...

  8. STM32必备知识点(面试和工作用的到)

    STM32必备知识点(面试和工作用的到) 文章目录 STM32必备知识点(面试和工作用的到) 前言 嵌入式C基础 一.位操作 1. 不改变其他位的值的状况下,对某几个位进行设值 2.移位操作提高代码的 ...

  9. Java 面试知识大全总结:程序员面试的必备,想拿offer来查漏补缺

    如果你参加了很多公司的面试,但都没有拿到心目中理想的offer,又或者拿到offer的概率特别低,原因很简单,你可能在技术知识点上有漏洞. Java面试,是对技术知识栈的梳理.考核.复盘 每一次Jav ...

最新文章

  1. OpenCV 【十八】图像平滑处理/腐蚀与膨胀(Eroding and Dilating)/开闭运算,形态梯度,顶帽,黑帽运算
  2. 人工智能的下一个道德挑战:如何对待动物
  3. freemarker的${!}
  4. AWS — AWS VPC 虚拟专用云
  5. python使用符号 表示单行注释-【转】Pyhton 单行、多行注释符号使用方法及规范...
  6. 【BZOJ4237】稻草人
  7. 创建应用服务器连接客户端
  8. 基于相关性分析系统性能瓶颈
  9. 计算机专业英语作业1,计算机专业英语作业1
  10. When we first heard of Linux
  11. Cocon90.Db调用方法
  12. ASIHttpRequest没更新,MKNetWorKit更优越
  13. 下面的代码能确定参数是否为奇数吗?
  14. 转为字符数组_py字符打印照片
  15. defined 用法
  16. Intel Technology Journal
  17. 一. Mybits简单使用
  18. 超级简单的Python爬虫教程,python爬虫菜鸟教程官网
  19. 跨站脚本攻击-----为什么要过滤危险字符串
  20. 图片怎么压缩?这些方法值得收藏

热门文章

  1. 大曾幽默打油诗_这才是真正的幽默打油诗,逗人一笑,又引人深思!
  2. 二分查找基础概念与经典题目(Leetcode题解-Python语言)二分数值型
  3. 「offer来了」从基础到进阶原理,从vue2到vue3,48个知识点保姆级带你巩固vuejs知识体系
  4. [C++11]不允许使用auto的四个场景
  5. [蓝桥杯][基础练习VIP]芯片测试-思维
  6. [蓝桥杯2015决赛]五星填数-枚举+数论
  7. FatMouse and Cheese HDU - 1078(记忆化搜索入门模板)
  8. word List 05
  9. Hibernate与MyBatis对比
  10. (CCPC 2020 网络选拔赛)HDU 6900 Residual Polynomial(分治 + NTT)