多线程面试

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

1、 死锁的发生原因和怎么避免

死锁,简单来说就是两个或者两个以上的线程在执行的过程中,争夺同一个共享
资源造成的相互等待的现象。
如果没有外部干预,线程会一直阻塞无法往下执行,这些一直处于相互等待资源
的线程就称为死锁线程。

导致死锁的条件有四个,也就是这四个条件同时满足就会产生死锁。
互斥条件,共享资源 X 和 Y 只能被一个线程占用;
请求和保持条件,线程 T1 已经取得共享资源 X,在等待共享资源 Y 的时候,不
释放共享资源 X;
不可抢占条件,其他线程不能强行抢占线程 T1 占有的资源;
循环等待条件,线程 T1 等待线程 T2 占有的资源,线程 T2 等待线程 T1 占有的
资源,就是循环等待。
导致死锁之后,只能通过人工干预来解决,比如重启服务,或者杀掉某个线程。
所以,只能在写代码的时候,去规避可能出现的死锁问题。
按照死锁发生的四个条件,只需要破坏其中的任何一个,就可以解决,但是,互
斥条件是没办法破坏的,因为这是互斥锁的基本约束,其他三方条件都有办法来
破坏:

  • 对于“请求和保持”这个条件,我们可以一次性申请所有的资源,这样就不存在等
    待了。
  • 对于“不可抢占”这个条件,占用部分资源的线程进一步申请其他资源时,如果申
    请不到,可以主动释放它占有的资源,这样不可抢占这个条件就破坏掉了。
  • 对于“循环等待”这个条件,可以靠按序申请资源来预防。所谓按序申请,是指资
    源是有线性顺序的,申请的时候可以先申请资源序号小的,再申请资源序号大的,
    这样线性化后自然就不存在循环了。

2、讲一下 wait 和 notify 这个为什么要在synchronized 代码块中?

wait 和 notify 用来实现多线程之间的协调,wait 表示让线程进入到阻塞状态,
notify 表示让阻塞的线程唤醒。
wait 和 notify 必然是成对出现的,如果一个线程被 wait()方法阻塞,那么必然需
要另外一个线程通过 notify()方法来唤醒这个被阻塞的线程,从而实现多线程之
间的通信。
在多线程里面,要实现多个线程之间的通信,除了管道流以外,只能通过共享变
量的方法来实现,也就是线程 t1 修改共享变量 s,线程 t2 获取修改后的共享变
量 s,从而完成数据通信。
但是多线程本身具有并行执行的特性,也就是在同一时刻,多个线程可以同时执
行。在这种情况下,线程 t2 在访问共享变量 s 之前,必须要知道线程 t1 已经修
改过了共享变量 s,否则就需要等待。
同时,线程 t1 修改过了共享变量 S 之后,还需要通知在等待中的线程 t2。
所以要在这种特性下要去实现线程之间的通信,就必须要有一个竞争条件控制线
程在什么条件下等待,什么条件下唤醒。

而 Synchronized 同步关键字就可以实现这样一个互斥条件,也就是在通过共享
变量来实现多个线程通信的场景里面,参与通信的线程必须要竞争到这个共享变
量的锁资源,才有资格对共享变量做修改,修改完成后就释放锁,那么其他的线
程就可以再次来竞争同一个共享变量的锁来获取修改后的数据,从而完成线程之
前的通信。
所以这也是为什么 wait/notify 需要放在 Synchronized 同步代码块中的原因,有
了 Synchronized 同步锁,就可以实现对多个通信线程之间的互斥,实现条件等
待和条件唤醒。

3、如果一个线程两次调用 start(),会出现什么问题?

在Java 里面,一个线程只能调用一次 start() 方法,第二次调用会抛出IllegalThreadStateException。
一个线程本身是具备一个生命周期的。
在 Java 里面,线程的生命周期包括 6 种状态。

  • NEW,线程被创建还没有调用 start 启动
  • RUNNABLE,在这个状态下的线程有可能是正在运行,也可能是在就绪队列里
    面等待操作系统进行调度分配 CPU 资源。
  • BLOCKED,线程处于锁等待状态。
  • WAITING,表示线程处于条件等待状态,当触发条件后唤醒,比如 wait/notify。
  • TIMED_WAIT,和 WAITING 状态相同,只是它多了一个超时条件触发。
  • TERMINATED,表示线程执行结束。
    当我们第一次调用 start()方法的时候,线程的状态可能处于终止或者非 NEW 状
    态下的其他状态。再调用一次 start(),相当于让这个正在运行的线程重新运行,不管从线程的安全性角度,还是从线程本身的执行逻辑,都是不合理的。
    因此为了避免这个问题,在线程运行的时候会先判断当前线程的运行状态。

4、线程池有哪些参数,各个参数的作用是什么?

线程池主要有如下7个参数:

  • corePoolSize(核心工作线程数):当向线程池提交一个任务时,若线程池已创建的线程数小于corePoolSize,即便此时存在空闲线程,也会通过创建一个新线程来执行该任务,直到已创建的线程数大于或等于corePoolSize时。

  • maximumPoolSize(最大线程数):线程池所允许的最大线程个数。当队列满了,且已创建的线程数小于maximumPoolSize,则线程池会创建新的线程来执行任务。另外,对于无界队列,可忽略该参数。

  • keepAliveTime(多余线程存活时间):当线程池中线程数大于核心线程数时,线程的空闲时间如果超过线程存活时间,那么这个线程就会被销毁,直到线程池中的线程数小于等于核心线程数。

  • workQueue(队列):用于传输和保存等待执行任务的阻塞队列。

  • unit:指定KeepAliveTime参数的时间单位。

  • threadFactory(线程创建工厂):用于创建新线程。threadFactory创建的线程也是采用new Thread()方式,threadFactory创建的线程名都具有统一的风格:pool-m-thread-n(m为线程池的编号,n为线程池内的线程编号)。

  • handler(拒绝策略):当线程池和队列都满了,再加入线程会执行此策略

5、线程池都有哪些状态?

线程池一共有五种状态, 分别是:

RUNNING :能接受新提交的任务,并且也能处理阻塞队列中的任务。

SHUTDOWN:关闭状态,不再接受新提交的任务,但却可以继续处理阻塞队列中已保存的任务。在线程池处于 RUNNING 状态时,调用 shutdown()方法会使线程池进入到该状态。

STOP:不能接受新任务,也不处理队列中的任务,会中断正在处理任务的线程。在线程池处于 RUNNING 或 SHUTDOWN 状态时,调用 shutdownNow() 方法会使线程池进入到该状态。

TIDYING:如果所有的任务都已终止了,workerCount (有效线程数) 为0,线程池进入该状态后会调用 terminated() 方法进入TERMINATED 状态。

TERMINATED:在terminated() 方法执行完后进入该状态,默认terminated()方法中什么也没有做。进入TERMINATED的条件如下:

  • 线程池不是RUNNING状态;

  • 线程池状态不是TIDYING状态或TERMINATED状态;

  • 如果线程池状态是SHUTDOWN并且workerQueue为空;

  • workerCount为0;

  • 设置TIDYING状态成功。

6、谈谈线程池的拒绝策略

当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:

1、AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

2、DiscardPolicy:也是丢弃任务,但是不抛出异常。

3、DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复该过程)。

4、CallerRunsPolicy:由调用线程处理该任务。

7、线程生命周期

多线程面试文章来源地址https://www.toymoban.com/news/detail-401013.html

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

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

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

相关文章

  • java八股文面试[数据库]——MySQL死锁的原因和处理方法

    java八股文面试[数据库]——MySQL死锁的原因和处理方法

    1) 表的死锁 产生原因 : 用户A访问表A(锁住了表A),然后 又访问表B ;另一个用户B访问表B(锁住了表B),然后企图 访问表A ;这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,这就死锁就产生了。 用户A--》A表(表

    2024年02月09日
    浏览(9)
  • redis是单线程的,那么他是怎么样避免阻塞的

    redis是单线程的,那么他是怎么样避免阻塞的

    Redis 实例在运行时,要和许多对象进行交互,这些不同的交互就会涉及不同的操作,下 面我们来看看和 Redis 实例交互的对象,以及交互时会发生的操作。 客户端 :网络 IO,键值对增删改查操作,数据库操作; 磁盘 :生成 RDB 快照,记录 AOF 日志,AOF 日志重写; 主从节点

    2024年02月13日
    浏览(14)
  • 操作系统考试复习——第三章 预防死锁 避免死锁

    预防死锁: 就是破坏死锁产生的四个条件之一就行。 0.破坏互斥条件:由于互斥条件是非共享设备所必须的所以,不仅不能改变还需要保证。因此我们主要考虑剩下的三个条件。 1. 破坏 \\\"请求和保持\\\" 条件 请求和保持也就是系统已经请求了一个资源它现在占有这个资源但是它

    2024年02月03日
    浏览(6)
  • 什么条件下会出现死锁,如何避免?

    什么条件下会出现死锁,如何避免?

    死锁,简单来说就是两个或者两个以上的线程在执行过程中,去争夺同一个共享资源导致相互等待的现象。如果没有外部干预,线程会一直处于阻塞状态,无法往下执行。这样一直等待处于阻塞状态的线程,被称为死锁线程。 产生死锁需要同时满足以下四个条件: 第一个:

    2024年02月12日
    浏览(7)
  • 【JavaEE面试题(九)线程安全问题的原因和解决方案】

    【JavaEE面试题(九)线程安全问题的原因和解决方案】

    大家观察下是否适用多线程的现象是否一致?同时尝试思考下为什么会有这样的现象发生呢? 原因是 1.load 2. add 3. save 注意:可能会导致 小于5w 想给出一个线程安全的确切定义是复杂的,但我们可以这样认为: 如果多线程环境下代码运行的结果是符合我们预期的,即在单线

    2024年02月16日
    浏览(6)
  • Golang Channel详解:安全并发通信与避免死锁方法

    深入了解Golang中的Channel,探讨其线程安全性、类型特性以及避免死锁的方法。学习如何正确初始化、存取数据,关闭Channel以及处理只读只写情况。

    2024年02月10日
    浏览(10)
  • 阿里二面:如何定位&避免死锁?连着两个面试问到了!

    在面试过程中,死锁是必问的知识点,当然死锁也是我们日常开发中也会遇到的一个问题,同时一些业务场景例如库存扣减,银行转账等都需要去考虑如何避免死锁,一旦线上发生了死锁,那可能年终不保。。。。。下面我们就来聊一聊死锁如何定位,以及如何避免。 死锁(

    2024年03月13日
    浏览(7)
  • 操作系统实验二死锁避免之银行家算法的模拟

    操作系统实验二死锁避免之银行家算法的模拟

    死锁  (1)定义  (2)死锁产生的原因  (3)死锁产生的必要条件  (4)死锁的处理策略 银行家算法  (1)核心思想  (2)数据结构  (3)算法描述    (4)  安全性检查算法 银行家算法的模拟 (1)数据结构 (2)完整代码 (3)测试 所谓死锁,是指多个进程因为竞争资

    2024年02月01日
    浏览(5)
  • Java避免死锁的几个常见方法(有测试代码和分析过程)

    Java避免死锁的几个常见方法(有测试代码和分析过程)

    目录 Java避免死锁的几个常见方法 死锁产生的条件 上死锁代码 然后 :jstack 14320 jstack.text Java避免死锁的几个常见方法 Java避免死锁的几个常见方法 避免一个线程同时获取多个锁。 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。 尝试使用定时锁,使

    2023年04月16日
    浏览(10)
  • 面试跳槽原因怎么说,高级UI强行进阶,秀出天际

    面试跳槽原因怎么说,高级UI强行进阶,秀出天际

    lateinit var rotateAnimator: ObjectAnimator override fun onCreate(savedInstanceState: Bundle?) { … setContentView(demoBinding.root) rotateAnimator = ObjectAnimator.ofFloat(demoBinding.musicAvatar, View.ROTATION, 0f, 360f) rotateAnimator.duration = 6000 rotateAnimator.repeatCount = -1 rotateAnimator.interpolator = LinearInterpolator() lifecycleScope.launch(

    2024年04月11日
    浏览(7)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包