Java面试题07

1.线程池都有哪些状态?

        线程池的状态有RUNNING(运行中)、SHUTDOWN(关闭中,不接受新任务)、 STOP(立即关闭,中断正在执行任务的线程)和TERMINATED(终止)。

1、RUNNING

(1) 状态说明:线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理。 
(02) 状态切换:线程池的初始化状态是RUNNING。换句话说,线程池被一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0!

2、 SHUTDOWN

(1) 状态说明:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务。 
(2) 状态切换:调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN。

3、STOP

(1) 状态说明:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。 
(2) 状态切换:调用线程池的shutdownNow()接口时,线程池由(RUNNING or SHUTDOWN ) -> STOP。

4、TIDYING

(1) 状态说明:当所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。 
(2) 状态切换:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。 
当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。

5、 TERMINATED

(1) 状态说明:线程池彻底终止,就变成TERMINATED状态。 
(2) 状态切换:线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED。

2.线程池中 submit()和 execute()方法有什么区别?

        submit()方法可以提交Callable任务,并返回Future对象;execute()方法只能提交 Runnable任务,无返回值。

  submit()execute()方法都是用于在线程池中提交任务的方法,但它们之间的主要区别在于任务的返回值和异常处理。

execute()方法是用于提交不需要返回值的任务。它接收一个Runnable对象作为参数,然后在线程池中执行这个Runnable对象。execute()方法没有返回值,因此不能用来获取任务的结果。如果任务执行过程中出现异常,execute()方法会直接抛出这个异常,而不会返回任何错误信息。

submit()方法则可以用于提交需要返回值的任务。它接收一个Callable对象作为参数,然后在线程池中执行这个Callable对象。submit()方法返回一个Future对象,可以通过这个Future对象来获取任务的结果。如果任务执行过程中出现异常,Future对象会保存这个异常,在获取任务结果时抛出。

总结一下,如果你需要获取任务的结果,那么应该使用submit()方法;如果你不需要获取任务的结果,或者你不需要等待任务执行完成,那么可以使用execute()方法。

3.在 java 程序中怎么保证多线程的运行安全?

        可以使用synchronized关键字、Lock接口、原子类等机制,确保多个线程访问共享资源时 不会出现数据竞争。

        

在Java程序中,有多种方法可以保证多线程的运行安全。以下是一些主要的策略:

  1. 同步(Synchronization): Java的synchronized关键字可以保证同一时间只有一个线程可以执行某个方法或者某个代码块,这样就可以避免多个线程同时修改同一个数据而引发的不一致问题。
  2. 使用volatile关键字volatile关键字可以保证变量的修改对所有线程可见,避免了线程之间的数据不一致问题。
  3. 使用Atomic:Java的java.util.concurrent.atomic包提供了一些原子操作类,如AtomicIntegerAtomicLong等,这些类可以保证对基本数据类型的操作是原子的。
  4. 使用线程安全的数据结构:Java提供了一些线程安全的数据结构,如VectorHashtable等,这些数据结构内部已经实现了同步,可以保证在多线程环境下的安全。
  5. 使用并发包(java.util.concurrent):Java的并发包提供了一些高级的并发工具,如SemaphoreCountDownLatchCyclicBarrier等,这些工具可以帮助你更好地控制线程的执行流程,避免多个线程同时访问共享资源的问题。
  6. 避免共享状态:尽可能地设计出无状态的程序,或者将状态信息局部化,可以减少线程间的竞争。如果必须共享状态,那么应该使用上述提到的方法来保证线程安全。
  7. 使用高级的并发类:Java 5以后,提供了一些更高级的并发类,如ThreadPoolExecutorScheduledThreadPoolExecutor等,它们可以更灵活地控制线程池的大小和任务的执行。
  8. 避免死锁:死锁是多线程编程中常见的问题,可以通过避免循环等待,按顺序获取锁,或者使用Java的ReentrantLock等机制来避免。

以上这些方法都可以在一定程度上保证多线程的运行安全,但需要注意的是,没有一种方法可以解决所有的并发问题。在实际编程中,需要根据具体的问题和场景来选择合适的方法。

        4.多线程锁的升级原理是什么?

在JVM中,锁会根据竞争情况从无锁升级为偏向锁、轻量级锁,最终升级为重量级锁,以适 应不同场景的线程竞争。

多线程锁的升级原理主要是指在Java中,当一个线程需要访问共享数据时,会先尝试获取锁,如果成功,则进入临界区执行操作;如果失败,则说明存在竞争,需要进行锁升级。

具体的锁升级过程如下:

  1. 在偏向锁状态下,对象头中的Mark Word被设置为偏向锁标记,并记录了持有锁的线程ID。因此,当一个线程访问共享数据时,无需进行同步操作,可以直接进入临界区执行操作。如果其他线程也需要访问该共享数据,此时需要升级为轻量级锁状态。
  2. 在轻量级锁状态下,对象头中的Mark Word被设置为指向锁记录的指针,同时锁记录结构体中包含了持有锁的线程ID和锁标志位等信息。此时,竞争线程会使用CAS(Compare and Swap)操作尝试获取锁,如果成功获取锁,则直接进入临界区执行操作;如果获取失败,则说明存在竞争,需要升级为重量级锁状态。
  3. 在重量级锁状态下,对象头中的Mark Word被设置为重量级锁标记,并将当前线程挂起,等待锁被释放后再唤醒线程进行竞争。由于重量级锁采用了操作系统内核的互斥机制,因此会引入较大的性能开销。

5.什么是死锁?

死锁是指两个或多个线程互相持有对方需要的锁,导致所有线程都无法继续执行。

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种相互等待的现象,若无外力作用,他们都将无法推进下去,陷入永久等待状态,这种现象称为死锁。

6.怎么防止死锁?

可以使用避免加锁顺序破坏、使用定时锁等方法来避免死锁的发生。

死锁是多线程编程中常见的问题,可以采取以下几种方法来预防和避免:

  1. 避免使用共享资源:尽量避免使用共享资源,因为共享资源是导致死锁的主要原因之一。如果必须使用共享资源,可以考虑使用锁或者信号量来进行同步。
  2. 按照顺序获取锁:当多个线程需要获取多个锁时,应该按照一定的顺序获取锁,避免出现循环等待的情况。例如,线程A获取锁1后才能获取锁2,而线程B获取锁2后才能获取锁1,这种情况容易导致死锁。
  3. 使用定时锁:对于需要长时间持有锁的情况,可以考虑使用定时锁。定时锁可以在一定时间后自动释放锁,避免长时间持有锁导致死锁的情况。
  4. 使用锁的分级管理:将不同的锁分为不同的级别,高级别的锁可以获得更多的资源,低级别的锁只能获得少量的资源。当低级别的锁被占用时,只有等待高级别的锁被释放后才能继续执行。
  5. 使用死锁避免算法:死锁避免算法是一种预防死锁的算法,它通过限制线程的行为来避免死锁的发生。例如,银行家算法是一种常用的死锁避免算法,它通过检查线程的请求是否会导致死锁来决定是否满足线程的请求。
  6. 使用锁的粒度更细:将锁的粒度变得更细,可以减少线程之间的竞争,降低死锁的概率。例如,使用多个独立的锁来保护不同的资源,而不是使用一个全局的锁。
  7. 避免线程饥饿:当一个线程长时间无法获取到需要的资源时,可能会导致死锁的发生。因此,应该尽量避免线程饥饿的情况,合理分配资源给不同的线程。

7.ThreadLocal 是什么?有哪些使用场景?

ThreadLocal是一种线程本地变量,每个线程都拥有自己的变量副本,常用于实现线程封闭 和线程上下文信息传递。

ThreadLocal 是一个Java的类,它用于创建线程局部变量。线程局部变量是每个线程自己独有的变量,它不会在线程之间共享。ThreadLocal的实例通常是在类中以静态字段的方式存在的。

ThreadLocal 的使用场景主要有以下几类:

  1. 方便同一个线程使用某一对象,避免不必要的参数传递。
  2. 线程间数据隔离(每个线程在自己线程里使用自己的局部变量,各线程间的ThreadLocal对象互不影响)。
  3. 获取数据库连接、Session、关联ID等。例如在 Spring 的事务管理器中,会通过 ThreadLocal 存储事务对象,以保证每个线程都在各自的 Connection 上进行数据库操作,避免出现线程安全问题。

然而,需要注意的是,在管理环境下(如 Web 服务器)使用 ThreadLocal 时要特别小心。因为工作线程的生命周期比任何应用变量的生命周期都要长,如果 ThreadLocal 变量在工作完成后没有得到释放,可能会导致内存泄露的风险。

8.说一下 synchronized 底层实现原理?

synchronized使用了对象的内部锁(监视器锁),它可以用来修饰代码块或方法,保证在 同一时刻只有一个线程可以进入临界区。

synchronized 是 Java 语言中的关键字,用于实现同步锁。它的底层实现原理是通过对象内部的一个叫做监视器锁(monitor)来实现的,而监视器锁本质又是依赖于底层的操作系统的 MutexLock(互斥锁)来实现的。

当一个线程要执行一个 synchronized 方法时,它需要先获得锁才能执行该方法。如果该线程已经获得了锁,则可以直接执行该方法;否则,该线程会被挂起,等待其他线程释放锁。一旦有线程释放了锁,就会唤醒等待的线程,让其获得锁并执行。

synchronized 底层实现原理还包括对代码块的加锁和解锁。当线程执行到 synchronized 代码块时,需要先获得锁才能执行后面的代码块。当线程执行到 synchronized 代码块的末尾时,会自动释放锁。这样可以保证同一时间只有一个线程可以执行该代码块。

每个对象自身维护着一个被加锁次数的计数器,当计数器不为0时,只有获得锁的线程才能再次获得锁。这个计数器的作用是防止死锁的发生。如果一个线程已经获得了多次锁,那么在下一次尝试获取锁时,该线程必须等待其他线程释放锁,否则就会发生死锁。

另外,synchronized 底层实现原理还涉及到对方法进行隐式的加锁和解锁。当线程要执行的方法被标注上 synchronized 时,需要先获得锁才能执行该方法。这个锁可以通过 ACC_SYNCHRONIZED 关键字来实现。当线程执行到 synchronized 方法时,会自动获得锁并执行该方法。当线程执行完 synchronized 方法后,会自动释放锁。

总之,synchronized 是 Java 语言中实现同步的关键字之一,它的底层实现原理是通过监视器锁和 MutexLock 来实现的。通过对方法进行隐式的加锁和解锁、对代码块进行加锁和解锁以及对计数器的使用,可以有效地保证多线程程序的正确性和稳定性。

9.synchronized 和 volatile 的区别是什么?

synchronized是一种独占锁,可以实现原子操作和临界区的同步;volatile是一种轻量级的 同步机制,用于保证可见性和禁止指令重排序。

synchronized和volatile是Java中两种不同的线程同步机制,它们有以下区别:

  1. 作用机制:synchronized是在方法或代码块前加上同步锁,保证同一时刻只有一个线程可以执行该段代码。而volatile关键字则用于保证多线程对变量的访问一致性,它不会阻塞线程,而是通过在内存和CPU之间建立缓存一致性协议来保证变量的可见性。
  2. 锁的粒度:synchronized可以修饰方法或代码块,而volatile只能修饰变量。
  3. 内存语义:synchronized可以保证被修饰的方法或代码块在每个线程中的执行是按照顺序进行的,不会出现数据不一致的问题。而volatile则无法保证这一点。
  4. 性能:使用synchronized会带来额外的开销,因为它需要进行线程阻塞和唤醒的操作。而volatile则不需要进行这些操作,因此性能相对较好。
  5. 原子性:synchronized可以保证被修饰的方法或代码块具有原子性,即这些代码不可分割。而volatile无法保证原子性。

综上所述,synchronized和volatile各有优缺点,需要根据具体的使用场景来选择合适的同步机制。

10.synchronized 和 Lock 有什么区别?

synchronized是Java内置的关键字,自动管理锁的获取和释放;Lock是Lock接口的实现 类,需要手动管理锁的获取和释放,提供了更灵活的锁控制。

synchronized和Lock是Java中两种不同的线程同步机制,它们有以下区别:

  1. 关键字和接口的区别:synchronized是一个关键字,而Lock是一个接口。
  2. 加锁方式:synchronized是隐式的加锁,而Lock是显式的加锁。
  3. 作用范围:synchronized可以作用于方法上或者代码块上,而Lock只能作用于代码块上。
  4. 底层实现:synchronized底层使用的是objectMonitor,而Lock底层使用的是AQS。
  5. 支持的锁类型:synchronized是非公平锁,而Lock可以是公平锁也可以是非公平锁。
  6. 超时机制:synchronized没有超时机制,而Lock中的trylock可以支持超时机制。
  7. 可中断性:synchronized不可中断,而Lock中的lockInterruptibly可中断的获取锁。
  8. 等待和唤醒机制:synchronized使用object类的wait和notify进行等待和唤醒,而Lock使用condition接口进行等待和唤醒(await和signal)。
  9. 个性化定制:Lock支持个性化定制,使用了模板方法模式,可以自行实现lock方法。

综上所述,synchronized和Lock都是Java中实现线程同步的机制,它们各有优缺点,需要根据具体的使用场景来选择合适的同步机制。

11.synchronized 和 ReentrantLock 区别是什么?

synchronized是关键字,无法中断等待获取锁的线程;ReentrantLock是Lock接口的实现 类,可以中断等待获取锁的线程。

synchronized 和 ReentrantLock 是Java中两种不同的线程同步机制,它们有以下区别:

  1. 关键字和接口的区别:synchronized是一个关键字,而ReentrantLock是一个接口。
  2. 加锁方式:synchronized是隐式的加锁,而ReentrantLock需要显式地调用lock()和unlock()方法来加锁和解锁。
  3. 锁的释放:synchronized在Java编译器下自动释放锁,而ReentrantLock需要程序员手动释放锁。
  4. 公平性:synchronized不具有公平性,而ReentrantLock可以通过构造函数来设置公平性。
  5. 锁状态查询:ReentrantLock提供了一个isHeldByCurrentThread()方法可以查询当前线程是否持有锁,而synchronized则没有这个功能。
  6. 锁升级和降级:synchronized不支持锁升级和降级,而ReentrantLock可以通过Condition接口来实现锁升级和降级。
  7. 等待可中断性:synchronized不支持等待可中断性,而ReentrantLock可以通过Condition接口来实现等待可中断性。
  8. 锁的可重入性:synchronized和ReentrantLock都支持可重入锁。
  9. 锁的粒度:synchronized可以作用于方法或代码块上,而ReentrantLock只可以作用于代码块上。

综上所述,synchronized和ReentrantLock都是Java中实现线程同步的机制,它们各有优缺点,需要根据具体的使用场景来选择合适的同步机制。

22.说一下 atomic 的原理?

atomic包提供了一些原子操作类,通过CAS(Compare and Swap)操作实现了多线程环 境下的线程安全,确保操作的原子性

Atomic(原子性)是指一个操作是不可中断的,即使在多线程环境下也不会被其他线程干扰。在并发编程中,原子性是保证数据一致性的关键。

Atomic操作的实现原理主要包括原子指令、自旋锁、读写锁和原子变量等。原子指令可以保证指令执行的不可中断性,自旋锁可以通过不断循环来等待锁的释放,读写锁可以实现对共享资源的并发访问,原子变量则可以保证对共享数据的原子性操作。

在实现Atomic时,需要保证操作的数据是共享的,并且需要保证对数据的访问是原子的。因此,需要使用锁或者其他同步机制来保证操作的原子性和可见性。同时,还需要考虑操作的具体实现方式,例如使用硬件级别的原子指令、使用自旋锁、读写锁或者使用原子变量等。

总之,Atomic的实现原理是通过保证操作的原子性和可见性来保证数据的一致性和可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/169945.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

函数调用分析

目录 函数相关的汇编指令 JMP指令 call指令 ret指令 VS2019正向分析main函数 总结调用函数堆栈变化规律 x64dbg分析调用函数 IDA分析调用函数 函数相关的汇编指令 JMP指令 JMP 指令表示的是需要跳转到哪个内存地址,相当于是间接修改了 EIP 。 call指令 ca…

图像分割方法

常见的图像分割方法有以下几种: 1.基于阈值的分割方法 灰度阈值分割法是一种最常用的并行区域技术,它是图像分割中应用数量最多的一类。阈值分割方法实际上是输入图像f到输出图像g的如下变换: 其中,T为阈值;对于物体的…

Django 路由配置(二)

一、路由 就是根据用户请求的URL链接来判断对应的出来程序,并返回处理结果,也是就是URL和django的视图建立映射关系. 二、Django请求页面的步骤 1、首先Django确定要使用的根URLconf模块,通过ROOT_URLCONF来设置,在settings.py配置…

试用无线调试器PowerDebugger小记

试用无线调试器PowerDebugger小记 文章目录 试用无线调试器PowerDebugger小记引言准备软硬件环境PowerDebugger 无线调试器EVB-YTM32B1LE0-Q64 开发板 开始调试小结参考文献 引言 多年前调试智能车时,抱着电脑连着小车在跑道上一边跑一边看数据的经历,让…

春秋云境靶场CVE-2022-30887漏洞复现(任意文件上传漏洞)

文章目录 前言一、CVE-2022-30887描述和介绍二、CVE-2021-41402漏洞复现1、信息收集2、找可能可以进行任意php代码执行的地方3、漏洞利用找flag 总结 前言 此文章只用于学习和反思巩固渗透测试知识,禁止用于做非法攻击。注意靶场是可以练习的平台,不能随…

深入解析SSD Wear Leveling磨损均衡技术:如何让你的硬盘更长寿?

SSD的存储介质是什么,它就是NAND闪存。那你知道NAND闪存是怎么工作的吗?其实,它就是由很多个晶体管组成的。这些晶体管里面存储着电荷,代表着我们的二进制数据,要么是“0”,要么是“1”。NAND闪存原理上是一…

Unity模拟薄膜干涉效果

Unity制作薄膜干涉效果,色彩斑斓的黑色石头 大家好,我是阿赵。   这次来做一个模拟薄膜干涉的彩色效果,Shader是使用ASE来连接,也算是ASE做复杂一点的效果的一个例子吧。 一、什么是薄膜干涉 以下解释来源于百度百科&#xff1…

白鳝:聊聊IvorySQL的Oracle兼容技术细节与实现原理

两年前听瀚高的一个朋友说他们要做一个开源数据库项目,基于PostgreSQL,主打与Oracle的兼容性,并且与PG社区版内核同步发布。当时我听了有点不太相信,瀚高的Highgo是在PG内核上增加了一定的Oracle兼容性的特性,一般也会…

#gStore-weekly | gBuilder功能详解之表单录入

gBuilder除了可以提供结构化数据映射以及非结构化数据抽取两种构建知识图谱的方式以外,还提供了表单录入的方式来构建知识图谱的数据,用户只需要根据设计好的schema将实体、属性以及关系通过填写表单的形式录入,再通过一键生成NT文件即可获得…

HTTP1.1升级HTTP2.0

HTTP1.1升级HTTP2.0 一,前言介绍 1.为什么要升级http2.0 HTTP2.0相比于HTTP1.x有以下几个优点: 二进制分帧:HTTP2.0将所有传输的信息分割为更小的消息和帧,并采用二进制格式对它们进行编码,这样可以更好地对数据进行…

国家开放大学平时作业训练题

卷代号:1400 机器人技术及应用 参考试题 一、单项选择题(每小题3分,共45分) 1.在变径轮和变形车轮的设计中,借鉴了( )的设计,使得车轮可以主动变形进行越障。 A.滑块机构 …

MR混合现实教学系统在汽车检修与维护课堂教学中的应用

传统的汽车检修与维护课堂教学主要依赖教师口头讲解和黑板演示,这种方式存在一定的局限性。首先,对于一些复杂的机械结构和操作过程,教师难以生动形象地展示给学生。其次,学生无法直接观察到实际操作中的细节和注意事项&#xff0…

Python CleverCSV指南,让CSV不再难搞

更多Python学习内容:ipengtao.com 大家好,我是涛哥,今天为大家分享 Python CleverCSV指南,让CSV不再难搞,文章58000字,阅读大约15分钟,大家enjoy~~ CleverCSV是一个Python库,专注于提…

vue过渡,vue3组合式API详细介绍

7.过渡效果 vue提供了两个内置组件,可以帮助你制作基于状态变化的过渡和动画 Transition会在一个元素或组件进入和离开DOM时应用动画TransitionGroup会在一个v-for列表中的元素或组件被插入,移动,或移除时应用动画 7-1过渡效果 过渡模式 <Transition mode"out-in&q…

系列二、Lock接口

一、多线程编程模板 线程 操作 资源类 高内聚 低耦合 二、实现步骤 1、创建资源类 2、资源类里创建同步方法、同步代码块 三、12306卖票程序 3.1、synchronized实现 3.1.1、Ticket /*** Author : 一叶浮萍归大海* Date: 2023/11/20 8:54* …

python趣味编程-5分钟实现一个贪吃蛇游戏(含源码、步骤讲解)

Python 贪吃蛇游戏代码是用 Python 语言编写的。在这个贪吃蛇游戏中,Python 代码是增强您在创建和设计如何使用 Python 创建贪吃蛇游戏方面的技能和才能的方法。 Python Tkinter中的贪吃蛇游戏是一个简单干净的 GUI,可轻松玩游戏。游戏设计非常简单,用户不会觉得使用和理解…

车载毫米波雷达行业发展5——企业

5.1 博世 5.1.1 公司简介 博世集团创立于 1886 年&#xff0c;业务涵盖汽车与智能交通技术、工业技术、消费品、能源与建 筑技术四大领域&#xff0c;是德国最大的工业企业之一、全球最大的汽车零部件供应商、最早研究车载毫米波雷达的企业之一。博世在高级辅助驾驶和自动驾驶…

数据库管理工具,你可以用Navicat,但我选DBeaver!

大家好&#xff0c;我是豆小匠。数据库GUI工具哪家强&#xff0c;众人遥指Navicat。 可是Navicat老贵了。 如果公司有正版授权的还好&#xff0c;如果没有正版授权&#xff0c;还不给你用盗版&#xff0c;那才叫绝绝子。 好了&#xff0c;主角登场&#xff0c;DBeaver&#x…

国产高云FPGA:纯verilog实现视频图像缩放,提供6套Gowin工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐国产高云FPGA相关方案推荐国产高云FPGA基础教程 3、设计思路框架视频源选择OV5640摄像头配置及采集动态彩条跨时钟FIFO图像缩放模块详解设计框图代码框图2种插值算法的整合与选择 Video Frame Buffer 图像缓存DDR3 Memory Interface 4、Go…

cadence layout lvs时出现error

Error&#xff1a;Schematic export failed or was cancelled.Please consult the transcript in the viewer window. 解决办法同下&#xff1a; cadence layout lvs时出现error-CSDN博客