Java多线程面试题

  • 1、什么是进程,什么是线程?
  • 2、请简要描述线程与进程的关系,区别及优缺点?
  • 3、为什么程序计数器、虚拟机栈、本地方法栈是线程私有的?
  • 4、说说并发与并行的区别?
  • 5、为什么要使用多线程呢?多线程会产生什么问题?
  • 6、说说线程的生命周期和状态?
  • 7、什么是上下文切换?
  • 8、什么是线程死锁?如何避免死锁?
  • 9、说说 sleep() 方法和 wait() 方法区别和共同点?
  • 10、为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法?
  • 11、说一说自己对于 synchronized 关键字的了解
  • 12、说说自己是怎么使用 synchronized 关键字,在项目中用到了吗
  • 13、谈谈 synchronized和ReentrantLock 的区别
  • 14、 volatile关键字
  • 15、并发编程的三个重要特性
  • 16、说说 synchronized 关键字和 volatile 关键字的区别
  • 17、ThreadLocal是什么?
  • 18、 为什么要用线程池?

1、什么是进程,什么是线程?

何为进程?
进程是程序的一次执行过程,是系统运行程序的基本单元,因此进程是动态的,系统运行一个程序即是一个进程从创建,运行到消亡的过程。当我们运行Java程序的时候,系统会启动一个JVM进程,main函数就是我们的主线程,同时会启动一个GC线程既守护线程。所以一个java程序最少有两个线程。

何为线程?
线程是比进程更小的一个存在,是比进程更小的一个执行单元,一个进程可以包括多个线程,与进程不同的是,线程之间会共享一块内存空间和系统资源,在java程序中就是堆和方法区。但每个线程会有各自的程序计数器、虚拟栈、本地方法栈。所以线程创建比进程创建所消耗的资源更小。也正因为如此,线程也被称为轻量级进程。

2、请简要描述线程与进程的关系,区别及优缺点?

从JVM角度来看线程和进程的关系。

可以看到一个进程有多个线程,线程共享堆和方法区,但线程私有的有程序计数器和虚拟机栈和本地方法栈。

区别是线程之间可以互相有联系,有共享的内存空间和系统资源,进程之间关系不大,线程执行开销小,但是多线程情况下可能会有内存溢出、死锁、资源调度不均匀之类的问题。

3、为什么程序计数器、虚拟机栈、本地方法栈是线程私有的?

程序计数器是记指令执行的行数和顺序的,上下文切换时候要保存住当前线程执行的点,所以每个线程有每个线程的程序计数器。虚拟机栈和本地方法栈存放的是该线程执行的方法,里面存放局部变量、常量引用等等,私有是为了保证局部变量不被别的线程访问到。

一句话简单了解堆和方法区
堆和方法区都是线程共享的资源,堆里面存放的是新创建的对象,所有的对象都在这里分配内存,方法区存放的是类信息、静态变量、常量、即时编译器编译的热点代码等等。

4、说说并发与并行的区别?

并发是指在一个时间段内,多个线程同时执行。
并行是指在一个时间点上,多个线程同时执行。

5、为什么要使用多线程呢?多线程会产生什么问题?

多线程可以提高程序的执行效率,多个人干活比一个人会更快。但多线程可能会产生内存溢出、死锁、系统资源调度不均匀、上下文切换消耗系统资源等问题。

6、说说线程的生命周期和状态?


线程在创建之后就进入新建状态,调用start()方法后进入就绪状态,当轮到该线程执行的时候进入运行状态,遇到线程调用资源需要等待的时候进入阻塞状态,调用wait方法进入等待状态,调用sleep(long)和wait(long)后进入超时等待状态,线程执行任务完成后进入终止状态。

7、什么是上下文切换?

多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的形式。当一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文切换。

概括来说就是:当前任务在执行完 CPU 时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换回这个任务时,可以再加载这个任务的状态。任务从保存到再加载的过程就是一次上下文切换。

上下文切换通常是计算密集型的。也就是说,它需要相当可观的处理器时间,在每秒几十上百次的切换中,每次切换都需要纳秒量级的时间。所以,上下文切换对系统来说意味着消耗大量的 CPU 时间,事实上,可能是操作系统中时间消耗最大的操作。

Linux 相比与其他操作系统(包括其他类 Unix 系统)有很多的优点,其中有一项就是,其上下文切换和模式切换的时间消耗非常少。

8、什么是线程死锁?如何避免死锁?

当A线程需要用到B线程所占用锁的资源,B线程需要用到A线程所占用锁的资源,双方互相等待,导致死锁。

死锁避免有三个方法:1、加锁顺序,加锁做好顺序,防止死锁。2、加锁时限,线程获得锁的时间受限制,比如只有5秒就得释放锁。3、死锁检测,比如A线程要拿B线程所占用锁的资源,在等待10秒后发现拿不到,就让B线程的锁释放,再让自己线程的锁释放掉。

9、说说 sleep() 方法和 wait() 方法区别和共同点?

wait方法会释放锁,sleep方法不会释放锁。
两者都会让线程暂停运行。
wait方法被调用后,需要同一个对象的另外一个线程调用notify或者notifyall方法。

10、为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法?

当我们new 一个Thread的时候,线程进入新建状态,调用了start方法后进入可运行状态,当线程进入执行状态就会自动调用run方法,如果直接调用run方法,程序会认为是main函数调用一个普通的run方法。
总结: 调用 start 方法方可启动线程并使线程进入就绪状态,而 run 方法只是 thread 的一个普通方法调用,还是在主线程里执行。

11、说一说自己对于 synchronized 关键字的了解

synchronized是为了解决多个线程访问同个资源的同步性,使用synchronized可以实现一个方法或者代码块只有一个线程执行。
synchronized是非公平锁、可重入锁、底层使用monitor对象实现锁机制。

12、说说自己是怎么使用 synchronized 关键字,在项目中用到了吗

在实现单理模式的时候使用了双重锁机制+volatile关键字实现。在一些方法需要实现只有一个线程进入的时候也会使用synchronized。

13、谈谈 synchronized和ReentrantLock 的区别

1、 两者都是可重入锁
2、synchronized 依赖于 JVM 而 ReentrantLock 依赖于 API
3、ReentrantLock可以实现公平锁、Condition等高级功能

14、 volatile关键字

在 JDK1.2 之前,Java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的。而在当前的 Java 内存模型下,线程可以把变量保存本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。

要解决这个问题,就需要把变量声明为volatile,这就指示 JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。

说白了, volatile 关键字的主要作用就是保证变量的可见性然后还有一个作用是防止指令重排序。

15、并发编程的三个重要特性

原子性 : 一个的操作或者多次操作,要么所有的操作全部都得到执行并且不会收到任何因素的干扰而中断,要么所有的操作都执行,要么都不执行。synchronized 可以保证代码片段的原子性。

可见性 :当一个变量对共享变量进行了修改,那么另外的线程都是立即可以看到修改后的最新值。volatile 关键字可以保证共享变量的可见性。

有序性 :代码在执行的过程中的先后顺序,Java 在编译器以及运行期间的优化,代码的执行顺序未必就是编写代码时候的顺序。volatile 关键字可以禁止指令进行重排序优化。

16、说说 synchronized 关键字和 volatile 关键字的区别

volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。
多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞
volatile关键字能保证数据的可见性,但不能保证数据的原子性;synchronized关键字两者都能保证。
volatile关键字主要用于解决变量在多个线程之间的可见性;而synchronized关键字解决的是多个线程之间访问资源的同步性。

17、ThreadLocal是什么?

通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢? JDK中提供的ThreadLocal类正是为了解决这样的问题。 ThreadLocal类主要解决的就是让每个线程绑定自己的值,可以将ThreadLocal类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。

如果你创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的本地副本,这也是ThreadLocal变量名的由来。他们可以使用 get() 和 set() 方法来获取默认值或将其值更改为当前线程所存的副本的值,从而避免了线程安全问题。

再举个简单的例子:

比如有两个人去宝屋收集宝物,这两个共用一个袋子的话肯定会产生争执,但是给他们两个人每个人分配一个袋子的话就不会出现这样的问题。如果把这两个人比作线程的话,那么ThreadLocal就是用来避免这两个线程竞争的。

18、 为什么要用线程池?

池化技术相比大家已经屡见不鲜了,线程池、数据库连接池、Http 连接池等等都是对这个思想的应用。池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。

线程池提供了一种限制和管理资源(包括执行一个任务)。 每个线程池还维护一些基本统计信息,例如已完成任务的数量。

这里借用《Java 并发编程的艺术》提到的来说一下使用线程池的好处:

降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

面试题:Java多线程相关推荐

  1. c语言线程面试题,java多线程面试题 PDF 下载

    主要内容: 基础知识 并发编程的优缺点 为什么要使用并发编程(并发编程的优点) 充分利用多核CPU的计算能力:通过并发编程的形式可以将多核CPU的计算能力发挥到极致,性能得到提升 方便进行业务拆分,提 ...

  2. java多线程及线程池使用

    Java多线程及线程池的使用 Java多线程 一.Java多线程涉及的包和类 二.Java创建多线程的方式 三.Java线程池 1. 创建线程池ThreadPoolExecutor的7个参数 2. 线 ...

  3. Java多线程常见面试题及答案汇总1000道(春招+秋招+社招)

    Java多线程面试题以及答案整理[最新版]Java多线程高级面试题大全(2021版),发现网上很多Java多线程面试题都没有答案,所以花了很长时间搜集,本套Java多线程面试题大全,汇总了大量经典的J ...

  4. 史上最全 Java 多线程面试题及答案

    这篇文章主要是对多线程的问题进行总结的,因此罗列了40个多线程的问题. 这些多线程的问题,有些来源于各大网站.有些来源于自己的思考.可能有些问题网上有.可能有些问题对应的答案也有.也可能有些各位网友也 ...

  5. 史上最全 Java 多线程面试题及答案 1

    这篇文章主要是对多线程的问题进行总结的,因此罗列了40个多线程的问题. 这些多线程的问题,有些来源于各大网站.有些来源于自己的思考.可能有些问题网上有.可能有些问题对应的答案也有.也可能有些各位网友也 ...

  6. 史上最全Java多线程面试题及答案

    这篇文章主要是对多线程的问题进行总结的,因此罗列了40个多线程的问题. 这些多线程的问题,有些来源于各大网站.有些来源于自己的思考.可能有些问题网上有.可能有些问题对应的答案也有.也可能有些各位网友也 ...

  7. JAVA多线程提高十四: 面试题

    前面针对多线程相关知识点进行了学习,那么我们来来看看常见的面试题: 1. 空中网面试题1 package com.kongzhongwang.interview; import java.util.c ...

  8. 15个顶级Java多线程面试题及回答(高级java工程师)

    Java 线程面试问题 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分.如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题.在投资银行业务中多线程和并发是 ...

  9. 15个顶级Java多线程面试题及答案

    转载自  15个顶级Java多线程面试题及答案 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分.如果你想获得更多职位,那么你应该准备很多关于多线程的问题. 他们会问面试者很多令人混淆 ...

  10. 精选30道Java多线程面试题

    转载自 精选30道Java多线程面试题 1.线程和进程的区别 2.实现线程有哪几种方式? 3.线程有哪几种状态?它们之间如何流转的? 4.线程中的start()和run()方法有什么区别? 5.怎么终 ...

最新文章

  1. Unique Paths II
  2. dac0832控制电机驱动流程图_智能电机驱动器让你的机器人控制更简单
  3. SQL 2005 Express 的“企业管理器” 下载
  4. Flex Builder 开发语言切换问题
  5. (转)AS3中的stage,this,root的区别
  6. 必背42个单词_高中英语必背100个常考单词,考试必考
  7. 求最近点对算法分析 closest pair algorithm
  8. MySQL划重点-查询-聚合
  9. POI上传Excel的小问题处理
  10. 使用ubuntu钉钉
  11. python提高——多继承、静态方法、类方法、property属性、魔法属性
  12. 关于使用Navicat
  13. tesseract如何在Linux下卸载,Tesseract装配
  14. java是否安装outlook,Java程序定期检查ms Outlook是否有新邮件
  15. python是一门胶水语言_python为何被称之为胶水语言
  16. TVB十大女星比美十大名花
  17. 他是清华姚班的天才少年,17 科满分传奇,32 岁斩获“诺贝尔风向标”斯隆奖...
  18. IAR 中的 Fatal Error[Lc002]: could not open file 解决办法
  19. java 创建新的图片,底色自己设定
  20. 月份加日期前面用on还是in_年月日前什么时候用in,什么时候用on

热门文章

  1. 2021数学建模B题及思路
  2. iptv组播和单播的区别
  3. itextsharp php,详解C#使用iTextSharp添加PDF水印的代码案例
  4. UML统一建模语言简介
  5. 王者荣耀ai视频战报ai剪辑生成方法
  6. CSS颜色渐变的按钮样式
  7. android 串口调试助手源码,android 串口调试工具源码
  8. Easy CHM 2.10
  9. 网易云音乐 linux x32,网易云音乐UWP版旧版本安装包 拒绝更新Win32转制版
  10. 华为USG6000V双机热备HRRP