java多线程面试题整理及答案

本文详细梳理了Java多线程相关的面试重点,包括线程与进程的区别、并行与并发的概念、线程状态、线程的创建方式、线程安全问题以及线程池的使用和配置。此外,还探讨了线程间的通信、锁机制、死锁预防、线程中断以及线程池的实现原理与合理配置。通过本文,读者可以深入理解Java多线程的各个方面。
摘要由CSDN通过智能技术生成

1. 什么是线程
      线程是程序执行的最小单位,它被包含在进程中,是进程中的实际运作单位。

2. 线程和进程的区别

       线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。CPU切换一个线程的花费比进程要小得多,同时创建一个线程的开销也比进程要小很多。

3. 并行和并发的区别

       并行(Parallel):指两个或者多个事件在同一时刻发生,即同时做某些事情,可以互不干扰的同时做几件事。例如垃圾回收时,多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。
      并发(Concurrent):指两个或多个事件在同一时间间隔内发生,即交替做不同事的能力,多线程是并发的一种形式。例如垃圾回收时,用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序在继续运行,而垃圾收集程序运行于另一个CPU上。

简单的举例帮助我们理解:

    "食堂打饭"很多人都经历过,放学后学生都冲向食堂,特别是12:00~12:30这个时间段人流量是最大的,这就叫作高并发。排队是解决并发的一种方法。"食堂准备多个窗口, 每个窗口学生都排队打饭"这就是并行了,这也是解决并发的一种方法。简而言之就是并发是多个事件在同一时间段执行,而并行是多个事件在同一时间点执行。

4. 守护线程是什么

    守护线程又称为后台线程,它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件,是个服务线程。

    正常创建的线程都是普通线程,或称为前台线程,守护线程与普通线程在使用上没有什么区别,但是他们有一个最主要的区别是在于进程的结束中。当一个进程中所有普通线程都结束时,那么进程就会结束。如果进程结束时还有守护线程在运行,那么这些守护线程就会被强制结束。守护线程拥有自动结束自己生命周期的特性。java中垃圾回收线程就是特殊的守候线程。

5. 创建线程有哪几种方式

    1. 继承Thread类(真正意义上的线程类,Thread类实现了Runnable接口)。

    2. 实现Runnable接口,重写run方法。

    3. 实现Callable接口

具体参考博客:https://blog.csdn.net/duan196_118/article/details/103898131

6.说一下 runnable 和 callable 有什么区别

   Runnable从JDK1.0开始就有了,Callable是在 JDK1.5增加的。Callable接口提供的call方法比run方法功能更强大,可以有返回值,支持泛型的返回值,可以声明抛出异常,而run()方法没有这些功能。

7. 线程有哪些状态

   新建,就绪,运行,阻塞,死亡。说出各种状态的特征及其如何转换。

8. sleep() 和 wait() 有什么区别

   1. 用法不同:sleep()时间到会自动恢复,wait()需要使用notify()/notifyAll()直接唤醒。

   2. 类不同:sleep()是Thread的方法,wait()是Object的方法。

   3. 释放锁:sleep()不释放锁,wait()释放锁。

9. notify()和 notifyAll()有什么区别

       这是一个刁钻的问题,因为多线程可以等待单监控锁,Java API 的设计人员提供了一些方法当等待条件改变的时候通知它们,但是这些方法没有完全实现。notify()方法不能唤醒某个具体的线程,所以只有一个线程在等待的时候它才有用武之地。而notifyAll()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行。

10. 线程的 run()和 start()有什么区别

      1. start() 方法用于启动线程,run() 方法用于执行线程的运行时代码。

      2. run() 可以重复调用,而 start() 只能调用一次。

      3. 第二次调用start() 必然会抛出运行时异常

11. Java中如何停止一个线程

   Java提供了很丰富的API但没有为停止线程提供API。JDK 1.0本来有一些像stop(), suspend() 和 resume()的控制方法但是由于潜在的死锁威胁因此在后续的JDK版本中他们被弃用了,之后Java API的设计者就没有提供一个兼容且线程安全的方法来停止一个线程。当run() 或者 call() 方法执行完的时候线程会自动结束,如果要手动结束一个线程,你可以用volatile 布尔变量来退出run()方法的循环或者是取消任务来中断线程。

12. 为什么wait, notify 和 notifyAll这些方法不在thread类里面

       这是个设计相关的问题,它考察的是面试者对现有系统和一些普遍存在但看起来不合理的事物的看法。回答这些问题的时候,你要说明为什么把这些方法放在 Object类里是有意义的,还有不把它放在Thread类里的原因。一个很明显的原因是JAVA提供的锁是对象级的而不是线程级的,每个对象都有锁,通过线程获得。如果线程需要等待某些锁那么调用对象中的wait()方法就有意义了。如果wait()方法定义在Threa

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值