面试宝典进阶之Java线程面试题

这篇具有很好参考价值的文章主要介绍了面试宝典进阶之Java线程面试题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

T1、【初级】线程和进程有什么区别?

(1)线程是CPU调度的最小单位,进程是计算分配资源的最小单位。
(2)一个进程至少要有一个线程。
(3)进程之间的内存是隔离的,而同一个进程中的线程之间是共享内存的。

T2、【初级】线程的创建有哪几种方式?

(1)继承Thread类,重写run方法。
(2)实现Runnable接口,重写run方法。
(3)实现Callable接口,重写call方法,结合Future创建线程。
(4)通过线程池创建。

T3、【初级】创建线程池的几种方式?

(1)使用Executors工具类创建线程池
(2)直接使用底层线程池构造函数创建线程:new ThreadPoolExecuto()

T4、【中级】线程池的参数有哪些?

    // 五参创建
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }
	// 七参创建
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        //---
    }

(1)corePoolSize 核心线程数
(2)maximumPoolSize 最大线程数
(3)keepAliveTime 空闲线程存活时间
(4)unit 空闲线程存活时间单位
(5)workQueue 工作队列

  • ArrayBlockingQueue
  • LinkedBlockingQuene
  • SynchronousQuene
  • PriorityBlockingQueue

(6)threadFactory 线程工厂
(7)handler 拒绝策略

  • 第一种拒绝策略是 AbortPolicy,这种拒绝策略在拒绝任务时,会直接抛出异常 RejectedExecutionException (属于RuntimeException),让你感知到任务被拒绝了,于是你便可以根据业务逻辑选择重试或者放弃提交等策略。
  • 第二种拒绝策略是 DiscardPolicy,这种拒绝策略正如它的名字所描述的一样,当新任务被提交后直接被丢弃掉,也不会给你任何的通知,相对而言存在一定的风险,因为我们提交的时候根本不知道这个任务会被丢弃,可能造成数据丢失。
  • 第三种拒绝策略是 DiscardOldestPolicy,如果线程池没被关闭且没有能力执行,则会丢弃任务队列中的头结点,通常是存活时间最长的任务,这种策略与第二种不同之处在于它丢弃的不是最新提交的,而是队列中存活时间最长的,这样就可以腾出空间给新提交的任务,但同理它也存在一定的数据丢失风险。
  • 第四种拒绝策略是 CallerRunsPolicy,相对而言它就比较完善了,当有新任务提交后,如果线程池没被关闭且没有能力执行,则把这个任务交于提交任务的线程执行,也就是谁提交任务,谁就负责执行任务。这样做主要有两点好处。
  • 第一点新提交的任务不会被丢弃,这样也就不会造成业务损失。
  • 第二点好处是,由于谁提交任务谁就要负责执行任务,这样提交任务的线程就得负责执行任务,而执行任务又是比较耗时的,在这段期间,提交任务的线程被占用,也就不会再提交新的任务,减缓了任务提交的速度,相当于是一个负反馈。在此期间,线程池中的线程也可以充分利用这段时间来执行掉一部分任务,腾出一定的空间,相当于是给了线程池一定的缓冲期。
理解思路
  • 队列已满,并且超过最大线程数,直接报异常
  • 队列已满,并且超过最大线程数,抛弃新添加的任务
  • 队列已满,并且超过最大线程数,抛弃最老的任务
  • 队列已满,并且超过最大线程数,交给提交任务的线程来执行

T5、【中级】多线程中常用的工具类有哪些?

(1)CountDownLaunch:让某一条线程等待其他线程执行完毕后再执行
(2)CycleBarrier:希望多条线程准备就绪之后,一起开始执行
(3)Condition:当希望指定唤醒某条线程时使用

T6、【中级】线程池都有哪些类型?

(1)缓存型线程池:

ExecutorService executorService = Executors.newCachedThreadPool();

(2)固定长度线程池

ExecutorService executorService = Executors.newFixedThreadPool(10);

(3)可定时执行的线程池

ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);

(4)单线程化线程池

ExecutorService executorService = Executors.newSingleThreadExecutor();
理解思路
  • 定长线程池
  • 变长线程池
  • 单线程池
  • 定时线程池

T7、【中级】线程的状态都有哪些?

面试宝典进阶之Java线程面试题,面试,java,职场和发展

T8、【中级】synchronized和static synchronized区别?

(1)synchronized是对象锁
(2)static synchronized是类锁

T9、【中级】synchronized与Lock有啥区别?

(1)实现方式不同:synchronized是Java语言内置的关键字,而Lock是一个Java API。

(2)粒度不同:synchronized锁的是整个方法或代码块,而Lock可以只锁定代码的一部分,可以灵活地控制加锁和解锁操作。

(3)可中断性不同:synchronized在获取锁失败时会等待,直到获取锁成功,而Lock可以通过tryLock()方法尝试获取锁,如果获取失败则可以终止等待。

(4)条件变量不同:Lock提供了Condition接口来实现线程之间的协调,而synchronized没有类似的概念。

(5)释放方式不同:synchronized可重入,即同一线程可以重复获取锁并解锁synchronized是自动释放锁。而Lock也可重入,但需要手动管理锁的计数器,Lock需要手动释放锁。

理解记忆
  • synchronized是java内置关键字,自动释放锁,可重入,非公平
  • Lock是接口,手动释放锁,可重入,可公平也可以不公平,默认是不公平
  • synchronized的底层原理是使用了操作系统的互斥对象(mutex)来实现的。

T10、【中级】start()和run()有啥区别?

(1)start()方法来启动线程,真正实现了多线程运行。这时无需等待 run 方法体代码执行完毕,可以直接继续执行下面的代码。
(2)通过调用 Thread 类的 start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。
(3)方法 run()称为线程体,它包含了要执行的这个线程的内容,线程就进入了运行状态,开始运行 run 函数当中的代码。 Run 方法运行结束, 此线程终止。然后 CPU 再调度其它线程。

T11、【初级】wait()和sleep()有啥区别?

(1)调用方式不同:wait()是Object类的方法,可以调用任何对象的wait()方法;而sleep()是Thread类的静态方法,只能调用当前执行线程的sleep()方法。

(2)执行的对象不同:wait()会释放对象锁,线程执行完wait()方法后进入等待池中,只能被其他线程调用notify()或notifyAll()方法唤醒;而sleep()不会释放对象锁,线程暂停一段时间后,会重新进入就绪状态,由操作系统进行调度。

(3)使用方式不同:wait()、notify()和notifyAll()通常用于相互协调的线程之间进行协作,如线程A等待线程B的信号来进行操作;而sleep()通常用于程序中对时间的控制,如在执行某个操作时需要暂停一段时间后再继续执行。

(4)异常处理不同:wait()和sleep()都可以抛出InterruptedException异常,但是InterruptedException异常的含义不同。wait()方法在等待过程中如果线程被中断,则会抛出InterruptedException异常;而sleep()方法在睡眠过程中如果线程被中断,则会清除中断标志位,不会抛出InterruptedException异常。

理解记忆
  • sleep()是静态方法,释放cpu但不释放锁,阻塞到时间了就继续执行
  • wait()是object对象的方法,释放锁,通过notify()唤醒

T12、【初级】notify()和notifyAll()有啥区别?

(1)notify()随机唤醒一条线程;
(2)notifyAll()唤醒全部的线程。

T13、悲观锁和乐观锁有啥区别?

(1)并发控制策略不同:悲观锁采用独占锁(排他锁)的方式,在读写数据之前先获得锁,以保证操作的原子性;而乐观锁采用版本号或时间戳等方式实现数据版本控制,在更新数据之前先检查版本号或时间戳是否一致,以确保在多线程环境下对数据的并发访问正确。

(2)加锁开销不同:悲观锁需要频繁的加锁和解锁,造成了较大的加锁开销和系统资源浪费;而乐观锁只需要在更新操作时进行版本号或时间戳的比较,不需要进行加锁和解锁操作,因此开销较小。

(3)适用场景不同:悲观锁适用于多写少读的情况,例如数据库的更新操作;而乐观锁适用于多读少写的情况,例如缓存中数据的更新。

(4)冲突处理方式不同:悲观锁在获取锁失败时会进入等待队列等待锁的释放,从而避免了数据的冲突问题;而乐观锁在检查版本或时间戳失败时需要回滚事务或重新执行操作,从而处理数据的冲突问题。。

理解记忆
  • 悲观锁,是重锁,是真正使用了锁
  • 乐观锁,是轻量级锁,实际上没有使用锁,而是通过CAS实现的

T14、join和CountDownLatch区别

(1)join:join()是线程对象的成员方法,功能是等待调用join()的线程对象执行完毕,才执行其它的逻辑
(2)CountDownLatch是一种灵活的闭锁实现,它维护了一个计数器,通过计数器控制一个或多个线程等待另一组事件发生,具体控制方法是:CountDownLatch调用countDown方法来递减计数器,表示有一个事件发生了,调用await在计数器为0之前保持阻塞。
(3)区别:
- join()的阻塞原理是不停检查join()所属的线程对象是否存活(也就是线程完全执行完毕),如果存活则让调用join()的线程保持阻塞。
- CountDownLatch的阻塞原理是仅仅关注计数器是否为0,若不为0才保持阻塞,它并不关注持有计数器的其它线程是否完全执行完毕。
显然join()能控制阻塞的范围比CountDownLatch小,且没有CountDownLatch那么灵活。

理解记忆
  • join是线程执行完了,才唤醒
  • CountDownLatch是一个计数器,为0时才唤醒

T15、多线程有哪些特性?

(1)原子性
(2)可见性:保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
(3)有序性:通过synchronized和lock来保证有序性

T16、什么是锁?

锁就是在多线程环境下为保证共享资源健康、线程安全的一种手段。
线程操作某个共享资源之前,先对资源加一层锁,保证操作期间没有其他线程访问资源,当操作完成后,再释放锁。

T17、什么是死锁?

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

T18、怎么避免死锁?

1、避免一个线程同时获取多个锁,如果必须使用多个锁,必须使用相同的加锁顺序。
2、降低锁的使用粒度,尽量保证一个锁只占用一个资源
3、尽可能使用定时锁,例如使用lock.tryLock(timeout)来替代使用内部锁机制

T19、分布式锁实有哪些实现方案?

1、基于数据库(唯一索引)
2、基于缓存(Redis,memcached,tair)
3、基于Zookeeper

T20、你都了解哪些锁?

面试宝典进阶之Java线程面试题,面试,java,职场和发展文章来源地址https://www.toymoban.com/news/detail-782051.html

到了这里,关于面试宝典进阶之Java线程面试题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 远程面试阿里、蚂蚁、京东、美团后整理份283页Java核心面试宝典

     本文整理了一些面试时面试官必问的知识点,其中包括了有基础知识、Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构等等。 以下是文档涉及的主要内容: !!以上提及到的所有的笔记

    2024年02月07日
    浏览(53)
  • 【操作宝典】IDE神器解密:IntelliJ IDEA详细教程,Java编程进阶指南!

    目录 🛸1. 新建Java项目 🛸2. 运行Java程序 🛸3. 创建springboot项目 方法一 导入jar包 ​编辑方法二 maven的安装配置 🛸4. 创建Vue项目 ​编辑4.1 配置node.js ​编辑4.2 idea运行 文件--新建--项目 JAVA模型--JDK 注意: 程序放在src里面 xxx.java则创建的类名只能为xxx 示例程序Hello.java 建议使

    2024年02月05日
    浏览(47)
  • Java 进阶(7) 创建线程

    1. 定义Thread类的⼦类,并重写该类的run()⽅法,该run()⽅法的⽅法体就代表了线程需要完成的任务,因此把run()⽅法称为线程执⾏体。 2. 创建Thread⼦类的实例,即创建了线程对象 3. 调⽤线程对象的start()⽅法来启动该线程 示例: 测试: 1. 定义Runnable接⼝的实现类,并重写该接⼝

    2023年04月16日
    浏览(42)
  • 【Java】多线程(进阶)

    乐观锁 乐观锁的基本思想是假设在数据的读取和修改过程中不会有其他的线程对其进行修改, ,因此乐观锁不会立即对数据进行加锁,而是在更新数据时检查是否发生了冲突,如果发现冲突(即数据被其他线程修改),则会进行回滚操作,乐观锁通常使用版本号,时间戳等机制来实现 优

    2024年02月10日
    浏览(32)
  • Java 进阶(12) 线程通信

    多个线程在处理同⼀个资源,但是处理的动作(线程的任务)却不相同。 为什么要处理线程间通信 多个线程并发执⾏时, 在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成⼀件任务,并且我们希望他们有规律的执⾏, 那么多线程之间需要⼀些协调通信,以此

    2023年04月16日
    浏览(35)
  • Java之多线程进阶

    目录 一.上节内容复习 1.线程池的实现 2.自定义一个线程池,构造方法的参数及含义 3.线程池的工作原理 4.拒绝策略 5.为什么不推荐系统提供的线程池 二.常见的锁策略 1.乐观锁和悲观锁 2.轻量级锁和重量级锁 3.读写锁和普通互斥锁 4.自旋锁和挂起等待锁 5.可重入锁和不可重入

    2024年02月05日
    浏览(47)
  • Java 进阶(8) 线程常用方法

    方法名 说明 public static void sleep(long millis) 当前线程主动休眠 millis 毫秒。 public static void yield() 当前线程主动放弃时间⽚,回到就绪状态,竞争下⼀次时间⽚。 public final void join() 允许其他线程加⼊到当前线程中。 public void setPriority(int) 线程优先级为1-10,默认为5,优先级越⾼,

    2023年04月16日
    浏览(36)
  • Java中的线程池技术进阶

    Java中的线程池技术是用于管理和复用线程的一种技术,它可以有效地提高应用程序的性能和响应速度。在Java中,线程池可以通过java.util.concurrent包中的ExecutorService接口和相关实现类来创建和使用。 以下是一些关于Java线程池技术的进阶知识: 线程池参数配置: corePoolSize:核

    2024年01月20日
    浏览(34)
  • 【Java多线程进阶】CAS机制

    前言 CAS指的是Compare-And-Swap(比较与交换),它是一种多线程同步的技术,常用于实现无锁算法,从而提高多线程程序的性能和扩展性。本篇文章具体讲解如何使用 CAS 的机制以及 CAS 机制带来的问题。 目录 1. 什么是CAS? 2. CAS的应用 2.1 实现原子类 2.2 实现自旋锁 3. CAS的ABA问

    2024年02月10日
    浏览(39)
  • mint-ui使用,面试一路绿灯Offer拿到手软,最新大厂程序员进阶宝典

    mint-ui 的使用 mint-ui官网 安装 npm install mint-ui -S 引入项目 全局引入(简单粗暴,一次引入所有组件) main.js // 引入全部组件 import Vue from ‘vue’; import Mint from ‘mint-ui’; import ‘mint-ui/lib/style.css’; // 有可能会报错, 找node_modules --》 mint-ui ?css Vue.use(Mint); 弹框 Toast组件 import {

    2024年04月08日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包