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中实现线程同步的机制,它们各有优缺点,需要根据具体的使用场景来选择合适的同步机制。

12.说一下 atomic 的原理?

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

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

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高防CDN如何预防攻击?

现在网络攻击事件越来越多,而且愈发凶猛,为了保障互联网业务能稳定正常的运行,市场上出现了很多高防产品,例如高防服务器、高防IP、高防CDN等等。其中究竟高防CDN怎么防攻击,能防哪些攻击?高防CDN如何实现防…

详解Python安装requests库的实例代码

文章目录 前言基本用法基本的get请求带参数的GET请求解析json关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 前…

为什么 Django 后台管理系统那么“丑”?

哈喽大家好,我是咸鱼 相信使用过 Django 的小伙伴都知道 Django 有一个默认的后台管理系统——Django Admin 它的 UI 很多年都没有发生过变化,现在看来显得有些“过时且简陋” 那为什么 Django 的维护者却不去优化一下呢?原文作者去询问了多…

网页开发如何实现简易页面跳动/跳转,html课堂练习/作业,页面ABC的相互跳转

先建一个文件夹&#xff0c;文件夹包含三个文件夹&#xff0c;三个文件夹分别包含各自的代码。(可以只建一个文件夹&#xff0c;文件夹包含各页面代码) 页面1的代码&#xff1a; <head> <meta http-equiv"Content-Type" content"text/html; charsetu…

使用Docker部署Python Flask应用的完整教程

一、引言 Docker是一种开源的容器化平台&#xff0c;可以将应用程序及其依赖项打包成一个独立的容器&#xff0c;实现快速部署和跨平台运行。本文将详细介绍如何使用Docker来部署Python Flask应用程序&#xff0c;帮助开发者更高效地构建和部署应用。 二、准备工作 在开始之前…

国产压力测试工具的主要作用

国产压力测试工具可以帮助软件开发和维护团队对系统进行全面的性能测试&#xff0c;以评估系统在高负载下的性能表现。以下是国产压力测试工具的主要作用&#xff1a; 性能评估&#xff1a;国产压力测试工具可以模拟多用户同时对系统进行访问和操作&#xff0c;通过对系统的响应…

​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第15章 面向服务架构设计理论与实践&#xff08;P527~554&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

pycharm 控制台中文乱码处理

今天使用pycharm&#xff0c;发现控制台输出又中文乱码了&#xff0c;看网上很多资料说把编码改为UTF-8&#xff0c;设置为并未生效&#xff0c;特此在此记录下本地设置。 1. 修改文件编码&#xff1a;Setting -> Editor ->File Encodings,修改配置如下&#xff1a; 2. …

ChatGPT/GPT4科研实践应用与AI绘图技术及论文高效写作

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

【每日OJ —— 225.用队列实现栈(队列)】

每日OJ —— 225.用队列实现栈&#xff08;队列&#xff09; 1.题目&#xff1a;225.用队列实现栈&#xff08;队列&#xff09;2.解法2.1.解法讲解&#xff1a;2.1.1.算法讲解2.1.2.代码实现2.1.3.提交通过展示 1.题目&#xff1a;225.用队列实现栈&#xff08;队列&#xff0…

【图像分类】【深度学习】【轻量级网络】【Pytorch版本】MobileNets_V2模型算法详解

【图像分类】【深度学习】【轻量级网络】【Pytorch版本】MobileNets_V2模型算法详解 文章目录 【图像分类】【深度学习】【轻量级网络】【Pytorch版本】MobileNets_V2模型算法详解前言MobleNet_V2讲解反向残差结构(Inverted Residuals)兴趣流形(Manifold of interest)线性瓶颈层…

微信小程序记住密码,让登录解放双手

密码是用户最重要的数据&#xff0c;也是系统最需要保护的数据&#xff0c;我们在登录的时候需要用账号密码请求登录接口&#xff0c;如果用户勾选记住密码&#xff0c;那么下一次登录时&#xff0c;我们需要将账号密码回填到输入框&#xff0c;用户可以直接登录系统。我们分别…

力扣贪心——跳跃游戏I和II

1 跳跃游戏 利用边界进行判断&#xff0c;核心就是判定边界&#xff0c;边界内所有步数一定是最小的&#xff0c;然后在这个边界里找能到达的最远地方。 1.1 跳跃游戏I class Solution {public boolean canJump(int[] nums) {int len nums.length;int maxDistance 0;int te…

卷积、卷积图像操作和卷积神经网络

好多内容直接看书确实很难坚持&#xff0c;就比如这个卷积&#xff0c;书上的一大堆公式和图表直接把人劝退&#xff0c;我觉得一般的学习流程应该是自顶向下&#xff0c;先整体后局部&#xff0c;先把握大概再推敲细节的&#xff0c;上来就事无巨细地展示对初学者来说很痛苦。…

2021年03月 Scratch(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 小猫在沙漠中旅行好不容易找到了一杯水,初始位置如下图所示,下面哪个程序可以帮助它成功喝到水? A: B: C: D:

OpenLayers实战,WebGL图层根据Feature要素的变量动态渲染多种颜色的三角形,适用于大量三角形渲染不同颜色

专栏目录: OpenLayers实战进阶专栏目录 前言 本章使用OpenLayers根据Feature要素的变量动态渲染不同颜色的三角形。 通过一个WebGL图层生成四种不同颜色的图形要素,适用于WebGL图层需要根据大量点要素区分颜色显示的需求。 更多的WebGL图层使用运算符动态生成样式的内容将会…

手机弱网测试工具:Charles

我们在测试app的时候&#xff0c;需要测试弱网情况下的一些场景&#xff0c;那么使用Charles如何设置弱网呢&#xff0c;请看以下步骤&#xff1a; 前提条件&#xff1a; 手机和电脑要在同一局域网内 Charles连接手机抓包 一、打开Charles&#xff0c;点击代理&#xff0c;…

黑马React18: 基础Part II

黑马React: 基础2 Date: November 16, 2023 Sum: 受控表单绑定、获取DOM、组件通信、useEffect、Hook、优化B站评论 受控表单绑定 受控表单绑定 概念&#xff1a;使用React组件的状态&#xff08;useState&#xff09;控制表单的状态 准备一个React状态值 const [value, se…

万界星空科技QMS质量管理系统功能

QMS质量管理系统结合质量决策、综合质量管理、过程质量控制三个层次要素&#xff0c;帮助企业实现产品全寿命周期质量数据的及时、灵活、准确和全面采集。 通过质量管理软件能够实现质量数据科学处理和应用&#xff0c;包括数据的系统化组织、结构化存贮、便捷式查询、定制化统…

不夸张地说,这是我见过最通俗易懂的,pytest入门基础教程!

Pytest简介 Pytest is a mature full-featured Python testing tool that helps you write better programs.The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries. 通过官方网站介绍…