Java后端面试复习7.24

  1. lock加锁解锁尝试获取锁方法
  2. lock底层基于什么实现
  3. lock和lock的底层实现分别面向什么用户
  4. lock和synchronized异同
  5. 如何选择合适的锁
  6. ReentrantLock如何实现冲入
  7. 内部类三个
  8. 公平和非公平获取锁怎么实现的
  9. RL默认公平还是非公平,构造参数
  10. ReentrantRedaWriteLock的特性
  11. 什么是AQS,内部属性
  12. AQS的设计模式,三类方法和对应作用
  13. 实现自定义锁步骤
  14. 同步队列的实现,入队出对
  15. 非公平所在队列中的竞争
  16. 读写锁获取两个锁的方法
  17. 读写锁的状态设计(怎么做到的用一个int类型变量维护两个锁)
  18. 写锁和读锁获取和释放的场景
  19. 支持所降级
  20. 为什么阻塞更耗时
  21. 自旋锁的默认重试次数
  22. 自适应自旋锁引入版本,怎么做的
  23. 乐观所悲观所
  24. 锁升级
  25. 公平所和非公平所优缺点
  26. 非可重入锁在重复调用同步资源为什么会死锁
  27. 共享锁和排它锁
  28. jwt的缺点
  29. CPU同步各个核心的手段
  30. 伪共享

  1. lock,unlock,tryLock
  2. AQS队列同步器
  3. lock面向锁的使用者,AQS面向锁的实现者,如果我们想自定义一个所可以实现AQS
  4. 相同点:都能进行并发控制,区别:sycn使用起来不灵活,只能对三种情况加锁,lock更灵活,可以自定义封锁对象。sync不用手动释放锁,lock需要释放锁。sync是排他锁,lock可以是排他锁也可以是共享锁
  5. 如果需要用到lock的尝试锁的方法,或者获取锁时可以被中断这些方法可以使用lock,剩下的就用sync。sync在1.6之前性能确实不好,1.6引入了锁的升级之后性能变好了,而且lock需要手动释放
  6. 通过计数器。当前线程获取锁之后,会将锁的计数值count+1,释放锁会执行-1,重入只需要将count++即可,当count为0才算彻底释放锁
  7. Sync,FairSync,UonfairSync,后两者继承自前者,ReentrantLock实现公平非公平就是依靠后两者实现的
  8. 通过同步队列实现,对于一个要获取锁的线程,公平锁会将其直接加在同步队列尾部,非公平锁会首先尝试与队列头部有、竞争锁,竞争成功就成功插队了,否则也加入到同步队列中
  9. 默认非公平锁,因为实际场景需要用到公平锁的场景不多,并且性能上非公平锁性能好,吞吐量高,传入参数true就是公平
  10. 提供了共享锁,内部有两种类型的锁,共享锁和排他锁,同时还是可重入锁。当当前线程获取到了写锁时,当前线程还可以获取读锁,但是其他线程不能获取任何锁,不同线程间可以获取读锁
  11. 队列同步器,int类型的同步状态以及一个FIFO的同步队列,status>表示当前线程获取锁的次数
  12. 模板模式,第一类访问和修改同步状态,第二类表示可重写的方法,第三类表示模板方法,定义了一些同步的基本操作
  13. 1实现Lock接口,2定义内部类sync继承AQS,3实现Lock定义的方法,实际上把锁的操作代理到了内部的AQS上
  14. 同步队列实际上是由Node节点构成的链表,每次都是对队列的首节点进行唤醒,当首节点释放同步状态时将唤醒下一个节点同时自己出队。当有新的线程来的时候直接加入到尾节点,
  15. 非公平锁首先尝试和下一个要获得同步状态的节点竞争,如果竞争成功就直接获得同步资源,就不用入同步队列,否则加入到同步队列尾部
  16. readLock(),writeLock()
  17. int32位,高16位保存读锁的重入次数,低16位保存写锁的重入次数
  18. 写锁:当前线程如果已经获取了写锁,那么次数+1,否则尝试获取写锁,如果此时其他线程占据写锁或者读锁,那么进入阻塞等待;读锁:如果有其他线程占据写锁,那么阻塞等待,否则读锁++
  19. 当当前线程占据写锁时,如果写操作执行完成想要读取数据,则尝试获取读锁,然后释放写锁
  20. 因为大多数场景下并发执行的代码会很少,占据的时间也就很少,实际上我们稍等下就可以获取锁了,但是如果阻塞的话会涉及到OS切换CPU状态,这种状态转换是非常耗时的
  21. 10次
  22. 1.6版本,让本次自选时间根据上一次在用一个锁上的自选时间来确定,如果某个锁很少被占用很长时间,或者过去的自旋尝试中很快就变为可用就让当前线程尝试自选更长的时间。
  23. 乐观锁认为我想要操作的同步资源没人和我竞争,所以我不会上锁,典型的例子就是CAS,他不上锁,仅仅是在更新的时候比较一下这个值在我执行期间有没有变化,变了就重新执行一遍,否则更新。悲观锁认为一定有人和我竞争同步资源,所以我直接上锁占着资源。典型的就是synchronized
  24. 对象由三部分组成:对象头,实际数据,填充字段。在对象头中保存了一些关键的信息比如hashcode,锁信息等待。当有线程想要获取我这个锁资源时,首先判断锁的对象头中的标志位,最后三位是001代表未上锁,此时当前线程获取锁资源,同时对象头的信息转为偏向锁,代表他偏向当前线程,同时将线程的id记录在对象头。后续如果还是当前线程获取锁就直接让他访问即可,不用加锁操作。当有其他线程竞争时,由偏向锁升级为轻量级锁,两个线程都通过CAS+自旋来竞争所。当有多个线程竞争时,有轻量级锁升级成重量级锁,避免过多无用的自旋操作浪费cpu资源
  25. 公平锁的获得顺序严格按照先到先得的思想,不存在线程饥饿的现象,但他降低了吞吐率,线程切换情况较多。非公平锁虽然存在线程饥饿的现象,但是他有效的利用cpu资源,不涉及向公平锁一样那么多的线程切换,吞吐率高
  26. 当前线程占据锁,但是他重复调用同步资源需要获取锁,而当前的锁不能冲入且被他自己占据,所以就导致他自己占着锁还等着获取锁造成死锁
  27. 共享锁是允许多个线程同时获得的,他们之间是不互斥的,ReentrantReadWriteLock中的读锁就是一个典型的共享锁。排他锁不允许其他线程获得,只能让当前线程独占,比如写锁,当当前线程持有写锁的时候,其他线程既不能获得写锁,也不能获取读锁
  28. 服务器不保存session状态,一旦token颁发了,在到期之前都始终有效。安全性依赖于加密算法。一旦泄露其他人也能获取该token的权限。
  29. 要保证写传播以及事务串行化,通过MESI协议
  30. 写直达把数据同时写入缓存和内存,写回当缓存被替换的时候刷新到内存
  31. AB两个核心读取了同一个cache line,对于一个数组的前两个数,A要修改第一个B要修改第二个,当A修改完第一个后,即使和B无关,B也要标记cache line失效,然后重新读取。
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值