搜索
首页Javajava教程归纳整理Java线程面试题

本篇文章给大家带来了关于java的相关知识,其中主要整理了线程面试题的相关问题,包括了sychronied 修饰普通方法和静态方法的区别、CAS 无锁编程的原理、volatile 和 synchronize 有什么区别等等内容,下面一起来看一下,希望对大家有帮助。

归纳整理Java线程面试题

推荐学习:《java视频教程

一、sychronied 修饰普通方法和静态方法的区别?什么是可见性?

       对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的 class 对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个 class 对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。
       有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存 在的,类锁其实锁的是每个类的对应的 class 对象。类锁和对象锁之间也是互不干扰的。
       可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
       由于线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量,那么对于共享变量 V,它们首先是在自己的工作内存,之后再同步到主内存。可是并不会及时的刷到主存中,而是会有一定时间差。很明显,这个时候线程 A 对变量 V 的操作对于线程 B 而言就不具备可见性了 。
       要解决共享对象可见性这个问题,我们可以使用 volatile 关键字或者是加锁。

二、锁分为哪几类。

在这里插入图片描述

三、CAS 无锁编程的原理。

       使用当前的处理器基本都支持 CAS()的指令,只不过每个厂家所实现的算法并不一样,每一个 CAS 操作过程都包含三个运算符:一个内存地址 V,一个期望的值 A 和一个新值 B,操作的时候如果这个地址上存放的值等于这个期望的值 A,则将地址上的值赋为新值 B,否则不做任何操作。
       CAS 的基本思路就是,如果这个地址上的值和期望的值相等,则给其赋予新值, 否则不做任何事儿,但是要返回原值是多少。循环 CAS 就是在一个循环里不断的 做 cas 操作,直到成功为止。 还可以说说 CAS 的三大问题。

四、ReentrantLock 的实现原理。

       线程可以重复进入任何一个它已经拥有的锁所同步着的代码块, synchronized、ReentrantLock 都是可重入的锁。在实现上,就是线程每次获取锁时判定如果获得锁的线程是它自己时,简单将计数器累积即可,每释放一次锁, 进行计数器累减,直到计算器归零,表示线程已经彻底释放锁。底层则是利用了 JUC 中的 AQS 来实现的。

五、AQS 原理。

       是用来构建锁或者其他同步组件的基础框架,比如 ReentrantLock、 ReentrantReadWriteLock 和 CountDownLatch 就是基于 AQS 实现的。它使用了一 个 int 成员变量表示同步状态,通过内置的 FIFO 队列来完成资源获取线程的排队工作。它是 CLH 队列锁的一种变体实现。它可以实现 2 种同步方式:独占式,共 享式。
       AQS 的主要使用方式是继承,子类通过继承 AQS 并实现它的抽象方法来管理同步状态,同步器的设计基于模板方法模式,所以如果要实现我们自己的同步工具类就需要覆盖其中几个可重写的方法,如 tryAcquire、tryReleaseShared 等等。
       这样设计的目的是同步组件(比如锁)是面向使用者的,它定义了使用者与同步组件交互的接口(比如可以允许两个线程并行访问),隐藏了实现细节;同步器面向的是锁的实现者,它简化了锁的实现方式,屏蔽了同步状态管理、线程的排队、等待与唤醒等底层操作。这样就很好地隔离了使用者和实现者所需关注的领域。
       在内部,AQS 维护一个共享资源 state,通过内置的 FIFO 来完成获取资源线程的排队工作。该队列由一个一个的 Node 结点组成,每个 Node 结点维护一个 prev 引用和 next 引用,分别指向自己的前驱和后继结点,构成一个双端双向链 表。

六、Synchronized 的原理以及与ReentrantLock 的区别。

       synchronized (this)原理:涉及两条指令:monitorenter,monitorexit;再说同步方法,从同步方法反编译的结果来看,方法的同步并没有通过指令 monitorenter 和 monitorexit 来实现,相对于普通方法,其常量池中多了 ACC_SYNCHRONIZED 标示符。
       JVM 就是根据该标示符来实现方法的同步的:当方法被调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取 monitor,获取成功之后才能执行方法体,方法执行完后再释放 monitor。在方法执行期间,其他任何线程都无法再获得同一个 monitor 对象。

七、Synchronized 做了哪些优化

       引入如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁、逃逸分析等技术来减少锁操作的开销。

  • 逃逸分析:如果证明一个对象不会逃逸方法外或者线程外,则可针对此变量进行优化:
  • 同步消除: synchronization Elimination,如果一个对象不会逃逸出线程,则对此变量的同步措施可消除。
  • 锁消除和粗化锁消除:虚拟机的运行时编译器在运行时如果检测到一些要求同步的代码上不可能发生共享数据竞争,则会去掉这些锁。
  • 锁粗化:将临近的代码块用同一个锁合并起来。 消除无意义的锁获取和释放,可以提高程序运行性能。

八、Synchronized static 与非 static 锁的区别和范围。

       对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的 class 对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个 class 对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。
       有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存 在的,类锁其实锁的是每个类的对应的 class 对象。类锁和对象锁之间也是互不干扰的。

九、volatile 能否保证线程安全?在 DCL 上的作用是什么?

       不能保证,在 DCL 的作用是:volatile 是会保证被修饰的变量的可见性和有序性, 保证了单例模式下,保证在创建对象的时候的执行顺序一定是

  1. 分配内存空间
  2. 实例化对象 instance
  3. 把 instance 引用指向已分配的内存空间,此时 instance 有了内存地址,不再为 null 了的步骤, 从而保证了 instance 要么为 null 要么是已经完全初始化好的对象。

十、volatile 和 synchronize 有什么区别?

       volatile 是最轻量的同步机制。 volatile 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。但是 volatile 不能保证操作的原子性,因此多线程下的写复合操作会导致线程安全问题。
       关键字 synchronized 可以修饰方法或者以同步块的形式来进行使用,它主要确保多个线程在同一个时刻,只能有一个线程处于方法或者同步块中,它保证了线程对变量访问的可见性和排他性,又称为内置锁机制。

十一、什么是守护线程?你是如何退出一个线程的?

       Daemon(守护)线程是一种支持型线程,因为它主要被用作程序中后台调 度以及支持性工作。这意味着,当一个 Java 虚拟机中不存在非 Daemon 线程的时候,Java 虚拟机将会退出。可以通过调用 Thread.setDaemon(true)将线程设置为 Daemon 线程。我们一般用不上,比如垃圾回收线程就是 Daemon 线程。
       线程的中止:要么是 run 执行完成了,要么是抛出了一个未处理的异常导致线程提前结束。 暂停、恢复和停止操作对应在线程 Thread 的 API 就是 suspend()、resume()和 stop()。 但是这些 API 是过期的,也就是不建议使用的。因为会导致程序可能工作在不确定状态下。
       安全的中止则是其他线程通过调用某个线程 A 的 interrupt()方法对其进行中断操作,被中断的线程则是通过线程通过方法 isInterrupted()来进行判断是否被中断, 也可以调用静态方法 Thread.interrupted()来进行判断当前线程是否被中断,不过 Thread.interrupted()会同时将中断标识位改写为 false。

十二、sleep 、wait、yield 的区别,wait 的线程如何唤醒它?

       yield()方法:使当前线程让出 CPU 占有权,但让出的时间是不可设定的。也不会释放锁资源。所有执行 yield()的线程有可能在进入到就绪状态后会被操作系统再次选中马上又被执行。
       yield() 、sleep()被调用后,都不会释放当前线程所持有的锁。
       调用 wait()方法后,会释放当前线程持有的锁,而且当前被唤醒后,会重新去竞争锁,锁竞争到后才会执行 wait 方法后面的代码。
       Wait 通常被用于线程间交互,sleep 通常被用于暂停执行,yield()方法使当前线程让出 CPU 占有权。
       wait 的线程使用 notify/notifyAll()进行唤醒。

十三、sleep 是可中断的么?

       sleep 本身就支持中断,如果线程在 sleep 期间被中断,则会抛出一个中断异常。

十四、线程生命周期。

Java 中线程的状态分为 6 种:

  1. 初始(NEW):新创建了一个线程对象,但还没有调用 start()方法。
  2. 运行(RUNNABLE):Java 线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。 线程对象创建后,其他线程(比如 main 线程)调用了该对象的 start()方法。 该状态的线程位于可运行线程池中,等待被线程调度选中,获取 CPU 的使用权, 此时处于就绪状态(ready)。就绪状态的线程在获得 CPU 时间片后变为运行中 状态(running)。
  3. 阻塞(BLOCKED):表示线程阻塞于锁。
  4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作 (通知或中断)。
  5. 超时等待(TIMED_WAITING):该状态不同于 WAITING,它可以在指定的时 间后自行返回。
  6. 终止(TERMINATED):表示该线程已经执行完毕。

在这里插入图片描述

十五、ThreadLocal 是什么?

       ThreadLocal 是 Java 里一种特殊的变量。ThreadLocal 为每个线程都提供了变量的副本,使得每个线程在某一时间访问到的并非同一个对象,这样就隔离了多个线程对数据的数据共享。
       在内部实现上,每个线程内部都有一个 ThreadLocalMap,用来保存每个线程所拥有的变量副本。

十六、线程池基本原理。

       在开发过程中,合理地使用线程池能够带来 3 个好处。
第一:降低资源消耗。
第二:提高响应速度。
第三:提高线程的可管理性。

  1. 如果当前运行的线程少于 corePoolSize,则创建新线程来执行任务(注意, 执行这一步骤需要获取全局锁)。
  2. 如果运行的线程等于或多于 corePoolSize,则将任务加入 BlockingQueue。
  3. 如果无法将任务加入 BlockingQueue(队列已满),则创建新的线程来处理任务。
  4. 如果创建新线程将使当前运行的线程超出 maximumPoolSize,任务将被拒绝,并调用 RejectedExecutionHandler.rejectedExecution()方法。

十七、有三个线程 T1,T2,T3,怎么确保它们按顺序执行?

       可以用 join 方法实现。

推荐学习:《java视频教程

以上是归纳整理Java线程面试题的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:CSDN。如有侵权,请联系admin@php.cn删除
带你搞懂Java结构化数据处理开源库SPL带你搞懂Java结构化数据处理开源库SPLMay 24, 2022 pm 01:34 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于结构化数据处理开源库SPL的相关问题,下面就一起来看一下java下理想的结构化数据处理类库,希望对大家有帮助。

Java集合框架之PriorityQueue优先级队列Java集合框架之PriorityQueue优先级队列Jun 09, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于PriorityQueue优先级队列的相关知识,Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,下面一起来看一下,希望对大家有帮助。

完全掌握Java锁(图文解析)完全掌握Java锁(图文解析)Jun 14, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java锁的相关问题,包括了独占锁、悲观锁、乐观锁、共享锁等等内容,下面一起来看一下,希望对大家有帮助。

一起聊聊Java多线程之线程安全问题一起聊聊Java多线程之线程安全问题Apr 21, 2022 pm 06:17 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

Java基础归纳之枚举Java基础归纳之枚举May 26, 2022 am 11:50 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于枚举的相关问题,包括了枚举的基本操作、集合类对枚举的支持等等内容,下面一起来看一下,希望对大家有帮助。

详细解析Java的this和super关键字详细解析Java的this和super关键字Apr 30, 2022 am 09:00 AM

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

Java数据结构之AVL树详解Java数据结构之AVL树详解Jun 01, 2022 am 11:39 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于平衡二叉树(AVL树)的相关知识,AVL树本质上是带了平衡功能的二叉查找树,下面一起来看一下,希望对大家有帮助。

一文掌握Java8新特性Stream流的概念和使用一文掌握Java8新特性Stream流的概念和使用Jun 23, 2022 pm 12:03 PM

本篇文章给大家带来了关于Java的相关知识,其中主要整理了Stream流的概念和使用的相关问题,包括了Stream流的概念、Stream流的获取、Stream流的常用方法等等内容,下面一起来看一下,希望对大家有帮助。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版