JAVA面试常见问题之锁机制篇
1、说说线程安全问题,什么是线程安全,如何保证线程安全
- 线程安全:就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。 线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。
- 如何保证:
- 使用线程安全的类;
- 使用synchronized同步代码块,或者用Lock锁;
- 多线程并发情况下,线程共享的变量改为方法局部级变量;
2、重入锁的概念,重入锁为什么可以防止死锁
概念:自己可以获取自己的内部锁。当线程请求自己持有的对象锁时,如果锁是重入锁,线程请求成功。
防止死锁原因:
3、产生死锁的四个条件
- 互斥:某种资源一次只允许一个进程访问,即该资源一旦分配给某个进程,其他进程就不能再访问,直到该进程访问结束。
- 占有且等待:一个进程本身占有资源(一种或多种),同时还有资源未得到满足,正在等待其他进程释放该资源。
- 不可抢占:别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来。
- 循环等待:存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。
参考:https://blog.csdn.net/guaiguaihenguai/article/details/80303835
4、如何检查死锁
- 使用Jconsole,JDK自带的图形化界面。
- 使用jstack输出线程dump信息到文件。
以上两种方式请参考:http://www.cnblogs.com/flyingeagle/articles/6853167.html
5、volatile 实现原理
作用:使用valatile修饰的成员变量,就是告知程序任何对该变量的访问均需要从共享内存中获取,而对它的改变必须同步刷新回共享内存,它能保证所有线程对变量访问的可见性。
原理:
- 强制把修改的数据写回内存。
- 在多处理器情况下使多处理器缓存的数据失效。

参考:https://mp.weixin.qq.com/s/XlowHAk8FPEYR3qtDIhJWw
6、synchronized 实现原理
作用:确保多个线程在同一个时刻,只能有一个线程处于方法或者同步块中,它保证了线程对变量访问的可见性和排他性。
原理:被synchronized 修饰的代码区,当线程想进入的时候,须先获取对象监视器(相当于钥匙,只存在一把),获取对象监视器成功的进入被修饰代码区,没有获取对象监视器的被阻塞在同步块和同步方法的入口处,进入BLOCKED状态。

参考:https://mp.weixin.qq.com/s/XlowHAk8FPEYR3qtDIhJWw
7、synchronized 与 lock 的区别
获取Lock对象的方法:Lock lock = new ReentrantLock();
- 首先synchronized是java内置关键字,在jvm层面,Lock是个java类;
- synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
- synchronized会自动释放锁,Lock需在finally中手工释放锁(
lock.unlock()方法释放锁),否则容易造成线程死锁; - 用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
- synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可)
- Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。
- Lock锁可以设置等待时间,到了时间自动放弃获取锁
参考:https://www.cnblogs.com/iyyy/p/7993788.html
8、AQS同步队列
队列同步器。它是构建锁或者其他同步组件的基础框架,通过这个框架可以简单实现一些相关锁。
参考:https://www.cnblogs.com/wait-pigblog/archive/2018/07/16/9315700.html
9、CAS无锁的概念、乐观锁和悲观锁
概念:CAS(compare and swap)是一种比较交换技术,可以用来鉴别线程技术,一旦检测到冲突就充当当前操作指导直到解决冲突。CAS机制中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。
乐观锁:大多基于版本来实现。将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为提交的数据是过期数据。
悲观锁:对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。
参考:https://blog.csdn.net/liubenlong007/article/details/53761730
10、常见的原子操作类
java.util.concurrent.atomic包,这个包中的原子操作类,提供了一种用法简单,性能高效,线程安全的更新一个变量的方式。
AtomicInteger、AtomicLong、AtomicBoolean、AtomicIntegerArray、AtomicReference(引用类型)、AtomicIntegerFieldUpdater(原子更新整形属性的更新器)
11、什么是ABA问题,出现ABA问题JDK是如何解决的
ABA问题:ABA问题出现在多线程或多进程计算环境中。
ABA问题举例描述:假设两个线程T1和T2访问同一个变量V,当T1访问变量V时,读取到V的值为A;此时线程T1被抢占了,T2开始执行,T2先将变量V的值从A变成了B,然后又将变量V从B变回了A;此时T1又抢占了主动权,继续执行,它发现变量V的值还是A,以为没有发生变化,所以就继续执行了。这个过程中,变量V从A变为B,再由B变为A就被形象地称为ABA问题了。
JDK解决方式:java提供了AtomicMarkableReference和AtomicStampedReference类帮助解决这个问题。AtomicStampedReference是利用版本戳的形式记录了每次改变以后的版本号
12、乐观锁的业务场景及实现方式
业务场景:适合读取操作比较频繁的操作。
实现方式:使用版本标识的方式来确定读到的数据和提交的数据是否一致。提交后修改版本标识,当检测出不一致时就丢弃或重试。
13、Java 8并法包下常见的并发类
ConcurrentHashMap、CopyOnWriteArrayList等
14、偏向锁、轻量级锁、重量级锁、自旋锁的概念
- 偏向锁:如果一个线程获得了锁,那么锁就进入了偏向模式。当这个线程再次请求锁时,无需再做任何同步操作。
- 轻量级锁:简单的将对象头部作为指针,指向持有锁的线程堆栈的内部,来判断一个线程是否持有对象锁。
- 重量级锁:
- 自旋锁:轻量级锁就会膨胀为重量级锁后,虚拟机为了避免线程真实的在操作系统层面挂起,虚拟机还会在做最后的努力
JAVA面试常见问题之锁机制篇的更多相关文章
- JAVA面试常见问题之常见集合篇
1.List 和 Set 区别 List 可以允许重复的对象. 可以插入多个null元素. 有序容器 Set 不允许重复的对象. 只能插入1个null元素 无序容器,可以使用TreeSet实现有序 2 ...
- Java 面试知识点解析(六)——数据库篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...
- Java 面试知识点解析(七)——Web篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...
- JAVA面试常见问题之基础篇
一. 面向对象的特征:继承.封装.(抽象).多态 继承:继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性. 封装:封装是保证软件部件具有优良的模块性的基础 ...
- Java 面试知识点解析(三)——JVM篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...
- Java多线程学习——synchronized锁机制
Java在多线程中使用同步锁机制时,一定要注意锁对对象,下面的例子就是没锁对对象(每个线程使用一个被锁住的对象时,得先看该对象的被锁住部分是否有人在使用) 例子:两个人操作同一个银行账户,丈夫在ATM ...
- java中常用的锁机制
基础知识 基础知识之一:锁的类型 锁就那么几个,只是根据特性,分为不同的类型 锁的概念 在计算机科学中,锁(lock)或互斥(mutex)是一种同步机制,用于在有许多执行线程的环境中强制对资源的访问限 ...
- Java内存区域和GC机制篇
Java内存区域和GC机制一.目录 1.Java垃圾回收概括 2.Java内存区域 3.Java对象的访问方式 4.Java内存访问机制 5.Java GC 机制 6.Java垃圾收集器 二.Java ...
- JAVA面试常见问题之Redis篇
Redis为单线程 1.Redis 有哪些数据类型 String 哈希 list set 有序set 2.Redis 内部结构 参考:https://www.cnblogs.com/chenpingz ...
随机推荐
- 侧滑关闭Activity的解决方案——SwipeBackLayout
项目地址:ikew0ng/SwipeBackLayout: An Android library that help you to build app with swipe back gesture. ...
- java_序列化
import java.io.*; class People implements Serializable { /* * 序列化和反序列化的时候,会抛出就NotSerializableExcepti ...
- linux centos&Ubuntu&RedHat更换软件源
linux三大版本更换软件源 前排提示,有的源可能已经失效,如果发现请留言或自行寻找其他源. 1.centos mv /etc/yum.repos.d/CentOS-Base.repo [--path ...
- Ubuntu Service说明与使用方法
1 什么是Ubuntu的Service 网上很多资料说, service就是linux中随开机自启动的, 并且在后台运行的程序. 个人认为, 至少对于Ubuntu来说, 这个说法是不太准确的, 这只不 ...
- 「题解」:[BZOJ4558]方
问题: 方 时间限制: 2 Sec 内存限制: 256 MB 题面 题目描述 上帝说,不要圆,要方,于是便有了这道题.由于我们应该方,而且最好能够尽量方,所以上帝派我们来找正方形 上帝把我们派到了一 ...
- JVM的内存空间
一.JVM运行起来,就会给内存划分空间,这块空间成为运行时数据区.运行时数据区主要划分为以下几部分内容: 1.栈 每一个线程运行起来的都会对应一个栈(线程栈),栈中的数据是该线程独有的,不会产生资源共 ...
- 一个windows 两个jar
设置两个子JAVA_HOME,一个总设置两个子JAVA_HOME:JAVA_HOME6 = C:\Program Files\Java\jdk1.6.0_43JAVA_HOME8 = C:\Progr ...
- js声明变量的三种方式
JS 声明变量的三种方式 (1)使用变量步骤:a.声明-->b.赋值-->3.调用 正确用法: <script type="text/javascript"> ...
- 网络工程师课程---3、IP与路由器(ip地址的主要作用是什么)
网络工程师课程---3.IP与路由器(ip地址的主要作用是什么) 一.总结 一句话总结: 用来标识一个节点的网络地址 划分网段 1.如何得到ip地址的网段号? ip和子网掩码 化成二进制后取 与运算 ...
- java流对象
Java和C++都是静态类型的面向对象编程语言 stream结尾都是字节流,reader和writer结尾都是字符流 区别: 就是读写的时候一个是按字节读写,一个是按字符. 实际使用通常差不多. 在读 ...