面试题总结

synchronize相关

  1. 可见性,就是一个线程的操作了主内存的数据,另一个线程也可以实时同步主内存的数据,比如就是一个线程在for循环他一直用的是自己工作区的副本,主内存中的变量如果更新了,这个线程如果还在用副本的值,就是没有可见性
  2. 原子性,就是要么一块代码都执行完,要么都不执行
  3. 排序性,按照顺序执行代码,不让jvm指令重排

synchronize如何做到这3个特性
因为有锁的话每次 加锁 和 释放锁 都会同步主内存信息

Java内存模型

计算机内存结构是
CPU
缓存
内存

Java内存空间
方法区
jvm栈
本地方法栈

程序计数器

Java内存模型分
主内存
线程工作空间

Java内存模型是一套规范,抽象出来的,不是真有这个物理结构,其主内存和工作空间都有可能存在内存和缓存中

主内存存放的是静态变量和成员变量,工作空间想操作主内存的数据,需要先拷贝到工作区副本,操作完在同步回去

在这里插入图片描述
具体步骤

  1. 先read到主内存的变量
  2. 在load加载到工作内存中
  3. 用到的时候就use操作
  4. 用完了assign分配回来改副本
  5. 然后在store存储到主内存
  6. 在write进变量
  7. 如果有锁的话,在上锁前即使方法区有该副本也先删除,同步过去最新的
  8. 解锁前,先同步回来在释放锁

syncornized两大特性

synchornize是可重入锁,意思就是synchornize嵌套,锁对象会有一个计数器 ,记录锁获取几次,获取+1,返回-1,计数器为0时释放锁
好处是,避免死锁,方便封装

synchornize是不可中断的 ,如果一个线程没获得锁会一直等着,处于block状态
lock也是,不过是wait状态
trylock可以设置时间,超过时间获得不到就干其他的去

synchornize原理

  • 在执行synchornize的时候会执行monitorenter指令,判断锁对象有没有monitor,如果没有则创建,然后判断monitor的owner是不是自己,
  • 如果空,设置monitor对象的owner为该线程,然后recursions加1,recursion是嵌套的意思,就是里面嵌套几个,
  • 如果是自己,recursions加1
  • 如果不是自己,线程阻塞执行到花括号结束的时候会执行monitorexit,recursions就会-1,当减到0时,线程释放锁

锁升级原理

重量级锁,因为他需要调用很多内核函数,涉及到用户态和内核态的切换,效率低
• 偏向锁,一个线程反复操作的话,会直接在对象头里保存线程ID,每次进同步代码块只需要看看ID是不是相同的,如果线程存在竞争,会先撤销锁
• 轻量级锁,在有线程竞争的时候,会把锁对象拷贝到栈帧里面的空间,线程拿不到锁不进人阻塞状态,而是自旋,自旋拿不到锁才会膨胀为重量级锁
• 自旋锁,因为线程拿不到锁转为阻塞状态比较耗时间,可能还没有转为阻塞状态,锁对象就释放了,所以自旋就是拿不到锁就多拿几次试试,具体次数是jvm根据以前自旋成功率来定
• 重量级锁,竞争不到线程会阻塞,不会自旋

jvm的锁优化

• 锁消除,在有些没有必要加锁的地方,jvm会通过逃逸分析判断,然后取消锁
• 锁粗化,就同一个对象的锁多次反复执行,会把锁放在这行代码外面,在锁里反复执行,不会去频繁创建锁

hashtable和currenthashtable

• Hashtable读和写都有锁,而且锁对象相同,写的时候不能读,而且操作一个桶的数据时,别的桶不能操作
 • currenthashmap读的时候没有锁,写的时候锁对象为该桶第一个节点,可以同时读写,同时操作不同的桶

synchornize和lock的区别

• lock是接口
• lock有读锁,可以多线程读
• lock有reenlock可以控制是否是公平锁,synchornize是非公平锁
• lock只能修代码块
• lock可以知道是否拿到了锁
• lock遇到异常不会自动释放锁
• lock可以用trylock来避免阻塞

CAS

因为synchornize的效率低,volite又只能保证可见性和有序性,这时候atomic相关类就来了,他可以保证可见性,原子性,有序性

atomic里面用volite修饰变量,保证了可见性和有序性,原子性采用了CAS操作

CAS原理
• 使用了乐观锁,使用到了3个变量,内存地址值,旧预估值,要修改的值
• 先从地址值里查出值赋给旧预估值
• 真正操作前先判断地址值里的值和旧预估值里的值是否一样,如果一样就改值,如果不一样证明其他线程操作过,就重新执行一遍
• 如果竞争太过激烈,线程大概率会被切走,一直重复执行会降低效率,甚至比synchornize还低
• 竞争不太激烈的话,效率比synchornize高

CAS的aba问题
• 线程1在执行代码时从内存中拿出值a赋值给预估值,线程2抢到线程,a变为b,又改回了a,但改了其他值,线程1在切换回来会赋值成功
• 判断版本号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值