您的当前位置:首页正文

Java后端面试复习7.24

来源:华佗健康网

  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失效,然后重新读取。

因篇幅问题不能全部显示,请点此查看更多更全内容