面试java基础锁

ClawHub的技术分享      2022-05-19     516

关键词:

技术图片


1、锁状态

锁的状态只能升级不能降级。

  • 无锁
    没有锁对资源进行锁定,所有线程都能访问并修改同一个资源,但同时只有一个线程能修改成功。其他修改失败的线程会不断重试,直到修改成功,如CAS原理和应用是无锁的实现。
  • 偏向锁
    偏向锁是指一段同步代码一直被一个线程访问,那个该线程会自动获取锁,降低获取锁的代价。
  • 轻量级锁
    是指当锁是偏向锁的时候,被另外的线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能。通过cas操作和自旋来解决加锁问题,自旋超过一定的次数或者已经有一个线程在自旋,又来一个线程获取锁时,轻量级锁会升级为重量级锁。
  • 重量级锁
    升级为重量级锁,等待锁的线程都会进入阻塞状态。

2、乐观锁与悲观锁

  1. 乐观锁,每次拿数据的时候认为别人都不会修改,在更新的时候再判断在此期间有没有更新数据,可以使用版本号等机制,适合读取多场景,提高性能。
  2. 悲观锁,每次拿数据都认为别人会修改,都会上锁,可以使用synchronized、独占锁Lock、读写锁等机制,适合写多的场景,保证写入操作正确。

    3、自旋锁与适应性自旋锁

  • 自旋锁:指当一个线程在获取锁的时候,如果锁已经被其他线程获取,那么该线程将循环等待,然后不断判断锁是否能获取成功,直到获取到锁才退出循环。
    优点:线程不进行上下文切换,减少了上下文切换的时间。
    存在的问题:如果线程持有锁的时间较长,其他线程进入循环,消耗cpu。
  • 自适应自旋锁:指的是自旋的时间不固定,由前一个在同一个锁上自旋的时间和锁拥有者的状态来决定。如果在同一个对象上,刚刚通过自旋成功获取过锁,且持有锁的线程正在运行中,那么虚拟机就会认为这次自旋很有可能再次成功。反之自旋操作很少成功获取锁,那么后面获取这个锁可能直接省略掉自旋的过程,直接阻塞线程。

4、公平锁与非公平锁

  1. 公平锁是指多个线程按照申请锁的顺序直接进入队列排队,队列中的第一个线程才能获取锁。
  2. 非公平锁是指线程先尝试获取锁,获取不到进入队列中排队,如果能获取到,则无需阻塞直接获取锁。

5、重入锁与非重入锁

重入锁:同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁,前提是锁对象是相同的。

6、共享锁与排他锁

  1. 共享锁是指一个锁可以被多个线程锁持有。
  2. 排它锁或者叫独享锁或者互斥锁 指锁一次只能被一个线程所持有。

7、读写锁

  1. 读锁是共享的,写锁是独占的。
  2. 读读之间不会互斥,读写互斥,写写互斥,读写锁提高了读的性能。

8、CAS

CompareAndSwap比较与交换,是一种无锁算法,原子类使用了CAS实现了乐观锁。
带来的问题:

  1. ABA问题
    解决思路在变量前面加版本号,每次变量更新的时候都将版本号 1,每次更新的时候要求版本>=当前版本(AtomicStampedReference)

  2. 循环时间长开销大,CAS操作如果长时间执行不成功,会导致其一直自旋,cpu消耗大。
  3. 只能保证一个共享变量的原子操作。
    可以把多个变量放在一个对象里面进行CAS操作。

9、锁优化

9.1、锁升级
  1. 偏向锁的升级
    线程A获取锁对象时,会在java对象头和栈帧中记录偏向的线程A的id,线程A再次获取锁时,只需要比较java头中的线程id与当前Id是否相等,如果一致则无需通过cas加锁解锁。如果不一致,说明有线程B来获取锁,那么要判断java头中偏向锁的线程是否存活,如果没有存活,锁对象被置为无锁状态,线程B可将锁对象置为B的偏向锁。如果存活,则查看A是否还需要继续持有对当前锁,如果不需要持有,则将锁置为无锁状态,偏向新的线程,如果还继续持有锁对象,则暂停A线程,撤销偏向锁,将锁升级为轻量级锁。
  2. 轻量级锁的升级
    线程A获取轻量级锁时会把锁的对象头复制到自己的线程栈针中,然后通过cas把对象头中的内容替换为A所记录的地址。此时线程B也想获取锁,发现A已经获取锁,那么线程B就自旋等待。等到自旋次数到了或者线程A正在执行,线程B自旋等待,此时来了线程C来竞争锁对象,这个时候轻量级锁就会膨胀为重量级锁。重量级锁会把未获得到锁对象的线程全部变为阻塞状态该,防止cpu空转。

    9.2、锁粗化

    将多个连续的加锁,解锁操作连接在一起,扩展成为一个范围更大的锁,避免频繁的加解锁操作。

    9.3、锁消除

    通过逃逸分析,去除不可能存在共享资源竞争的锁,通过这种方式消除没有必要的锁。

    10、synchronized底层实现

  • synchronized通过Monitor实现同步,Monitor依赖于底层操作系统互斥锁来实现线程同步。
  • java对象头是由markword(标记字段)和klass point(类型指针)组成。markword存储对象的hashcode,分代年龄和锁标志位信息。Klass point 指向对象元数据的指针,虚拟机通过这个指针来确定对象是哪个类的实例。
  • synchronized修饰同步代码块,是使用monitorenter和monitorexit来控制的,通过java对象头中的锁计数器。
  • 修饰方法时会将方法标识为ACCSYNCHRONIZE,JVM通过这个标志来判断方法是不是同步方法。

11、synchronized与ReentrantLock的区别

  1. 两者都是悲观锁,可重入锁。
  2. ReentrantLock 可中断,可以实现公平锁,可以绑定多个条件。
  3. ReentrantLock需要显示的调用锁和释放锁,synchronized属于java关键字,不需要显式的释放。

12、volatile关键字

  1. 保证变量内存可见。
  2. 禁止指令重排序。

volatile和synchronized的区别:

  • volatile不会阻塞,synchronized会阻塞。
  • volatile保证数据的内存可见性但不能保证原子性,synchronized两者都能保证。
  • volatile主要解决变量在线程之间的可见性,而synchronized主要解决多线程访问资源的同步性。

13、Atomic原子类实现

使用cas操作 volatile native方法保证同步。

14、AQS

AQS(AbstractQueuedSynchronizer)内部维护的是一个FIFO的双向同步队列,如果当前线程竞争锁失败,AQS会把当前线程以及等待状态信息构造成一个Node加入到同步队列中,同时在阻塞该线程。当获取锁的线程释放锁以后,会从队列中唤醒一个阻塞的节点线程。使用内部的一个state来控制是否获取锁,当state=0时表示无锁状态,state>0时表示已经有线程获取了锁。

15、AQS的组件

  1. semaphore 可指定多个线程同时访问某个共享资源。
  2. countDownLatch 一个线程A等待其他线程执行完成之后才继续执行。
  3. cyclicBarrier 一组线程等待至某个状态之后同时执行。

countDownLatch和CyclicBarrier的区别

  1. countDownLatch是一个线程等一组线程执行完成之后才执行, cyclicBarrier是一组线程互相等待至某个状态之后,同时执行。
  2. countDownLatch不能复用,cyclicBarrier可以重用。

16、锁降级

锁降级是指将写锁降级为读锁,这个过程就是当前线程已经获取到写锁的时候,再获取到读锁,随后释放写锁的过程,这么做的目的为的就是保证数据的可见性。

17、逃逸分析

  1. 逃逸分析就是分析对象的动态作用域,当一个对象在方法中被定义后,他可能被外部方法所引用,作为参数传递到其他方法中,成为方法逃逸,赋值给类变量或者可以被其他线程访问的实例变量成为线程逃逸。
  2. 使用逃逸分析,编译器可以对代码做优化。比如:同步省略(锁消除),将堆分配转化为栈分配,标量替换。
  3. 使用逃逸分析的缺点,没法保证逃逸分析的性能一定高于其他性能。极端的话经过逃逸分析后,所有的对象都逃逸了,那么逃逸分析的过程就浪费了。

技术图片

java面试-基础篇之5

说一说synchronized关键字synchronized是java语言中的一个关键字,如同public、private、trycatch等可以在Java中直接被编译器识别的具有功能性的单词。synchronized中文意思是同步的,也表示它在Java中主要负责的是多个线程之间资源的同步性... 查看详情

java基础高质量面试总结

Java基础相关面试总结Java工具类锁Java基础Java类加载Java工具类具体讲一讲几种线程安全的Map?Map有哪几种遍历方式?HashSet的去重原理是什么?HashTable是线程安全的吗?TreeSet是如何进行逆序的?Java中有哪些是有序的集合?锁Java中的锁有哪... 查看详情

阿里面试基础题

Java基础:hashmap结构;什么对象能做为keyhashtable,concurrentHashMap,hashtable比较String,StringBuilder,StringBuffer对象的深浅复制多线程:wait,sleep分别是谁的方法,区别countLatch的await方法是否安全,怎么改造线程池参数,整个流程描述背后的... 查看详情

大厂高频面试:java并发篇(线程6种状态线程池悲观锁vs乐观锁等)(代码片段)

并发篇🍌大厂高频面试:Java基础篇(算法、数据结构、基础设计模式)1.线程状态要求掌握Java线程六种状态掌握Java线程状态转换能理解五种状态与六种状态两种说法的区别六种状态及转换分别是新建当一个线程... 查看详情

java学习---面试基础知识点总结(代码片段)

Java中sleep和wait的区别①这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调... 查看详情

java基础面试每日3题:day14

目录1.为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法?2.说一说自己对synchronized关键字的了解3.数据库中的乐观锁和悲观锁1.为什么我们调用start()方法时会执行run()方法,为什么我们不... 查看详情

java基础知识回顾(面试资料)

1、JAVA程序优化;前端性能:http请求数量,CDN网络,使用压缩Java程序优化:单例,Future模式的非阻塞,线程池,使用NIO,减少上下文切换,减低锁竞争;使用redis缓存;若是springboot项目可以使用它的监控(spring-boot-admin-server)... 查看详情

多线程多线程面试常见基础内容(代码片段)

文章目录1.CAS1.1CAS介绍1.2CAS的应用1.2.1实现原子类1.2.2实现自旋锁1.3CAS的缺点1.4ABA问题2.synchronized工作原理2.1synchronized的特性2.2锁升级2.3消除锁2.4锁粗化3.Callable接口3.1Callable介绍3.2Callable的用法4.JUC(java.util.concurrent)的常见 查看详情

多线程多线程面试常见基础内容(代码片段)

文章目录1.CAS1.1CAS介绍1.2CAS的应用1.2.1实现原子类1.2.2实现自旋锁1.3CAS的缺点1.4ABA问题2.synchronized工作原理2.1synchronized的特性2.2锁升级2.3消除锁2.4锁粗化3.Callable接口3.1Callable介绍3.2Callable的用法4.JUC(java.util.concurrent)的常见 查看详情

java实习生常规技术面试题每日十题java基础

目录1.启动一个线程是用run()还是start()?. 2.线程的基本状态以及状态之间的关系。3.Set和List的区别,List和Map的区别?4.同步方法、同步代码块区别?5.描述Java锁机制。6.Comparable和Comparator接口是干什么的?列出它们... 查看详情

android面试题java基础

Android面试题(一)Java基础Android面试题(二)Android基础Android面试题(三)Java虚拟机Android面试题(四)设计模式Android面试题(五)数据结构/算法Android面试题(六)网络基础 查看详情

java面试经历汇总

java面试题2020百度第一篇一面1.手写ArrayList2.手写进制转换算法,求出一个数的二进制数1的个数3.JAVA基础,equals和==4.多线程方式、threadlocal,各种锁,synchronized和lock5.设计模式、spring类加载方式、实例保存在哪、aopioc、反射机制6... 查看详情

java面试通关要点汇总集

Java面试通关要点汇总集2018-08-11转自:Java面试通关要点汇总集文章目录1. 基础篇 1.1. 基本功 1.2. 集合 1.3. 线程 1.4. 锁机制2. 核心篇 2.1. 数据存储 2.2. 缓存使用 2.3. 消息... 查看详情

面试基础题

Java面试题01.面试的整体流程 Java面试题02.java的垮平台原理 Java面试题03.搭建一个java的开发环境 Java面试题04.java中int占几个字节 Java面试题05.java面向对象的特征 Java面试题06.装箱和拆箱 Java面试题07.==和equals... 查看详情

面试官问我“java中的锁有哪些?以及区别”,我跪了

在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类。介绍的内容如下:公平锁/非公平锁可重入锁独享锁/共享锁互斥锁/读写锁乐观锁/悲观锁分段锁偏向锁/轻量级锁/重量级锁自旋锁上面... 查看详情

java:cas(乐观锁)(代码片段)

本文讲解CAS机制,主要是因为最近准备面试题,发现这个问题在面试中出现的频率非常的高,因此把自己学习过程中的一些理解记录下来,希望能对大家也有帮助。什么是悲观锁、乐观锁?在java语言里,总有一些名词看语义跟... 查看详情

java基础面试

 *以下内容是我在准备java面试的时候觉得有用,面试官很可能会问的一些问题 *内容(除了代码)详情来自网络(学习的时候遇到不会的百度的(*^__^*)) *如果大家发现有什么地方不对,请告诉我。谢啦!!☆⌒(*^-゜)v&n... 查看详情

java多线程和并发基础面试问答(转载)

 JAVA多线程和并发基础面试问答  原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/  多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的... 查看详情