每天进步一点~

(ps: 文章内容及图片出处来自本人公众号~)

01、问:请谈谈你对并发编程优缺点的认识与理解 ~

答:

优点:充分利用多核CPU的计算能力,通过并发编程的形式将多核CPU的计算能力发挥到极致,性能得到提升。

方便进行业务的拆分。提高系统并发能力和性能:高并发系统的开发,并发编程会显得尤为重要,利用好多线程机制可以大大提高系统的并发能力及性能;面对复杂的业务模型,并行程序会比串行程序更适应业务需求,而并发编程更适合这种业务拆分。

缺点:并发编程的目的是为了提高程序的执行效率,提高程序运行速度,但并发编程并不是总能提高性能,有时还会遇到很多问题,例如:内存泄漏,线程安全,死锁等。

02、问:请简要描述一下并发编程的三要素

答:

原子性:原子是不可再分割的最小单元,原子性是指一个或多个操作要么全部执行成功,要么全部执行失败。

可见性:一个线程对共享变量的修改,另一个线程能看到(synchronized,volatile)

有序性:程序的执行顺序按照代码的先后顺序

线程安全的问题原因有:

1. 线程切换带来的原子性问题

2. 缓存导致的可见性问题

3. 编译优化带来的有序性问题

解决方案:

1.JDK Atomic开头的原子类、synchronized、LOCK,可以解决原子性问题

2.synchronized、volatile、LOCK,可以解决可见性问题

3.Happens-Before 规则可以解决有序性问题

03、问:并发和并行有什么区别吗?

答:

并发:多个任务在同一个CPU上,按照细分的时间片轮流交替执行,由于时间很短,看上去好像是同时进行的。

并行:单位时间内,多个处理器或多核处理器同时处理多个任务,是真正意义上的同时进行。

串行:有n个任务,由一个线程按照顺序执行。

04、问:谈谈什么是多线程 以及 多线程的优劣势?

答:定义:多线程是指程序中包含多个流,即在一个程序中可以同时进行多个不同的线程来执行不同的任务。

优点:

可以提高CPU的利用率,在多线程中,一个线程必须等待的时候,CPU可以运行其它线程而不是等待,这样就大大提高了程序的效率,也就是说单个程序可以创建多个不同的线程来完成各自的任务。

缺点:

线程也是程序,线程也需要占内存,线程也多内存也占的也多。

多线程需要协调和管理,所以需要CPU跟踪线程。

线程之间共享资源的访问会相互影响,必须解决禁用共享资源的问题。

05、​​​​​​​问:什么是线程与进程呢?

答:

进程:内存中运行的运用程序,每个进程都有自己独立的内存空间,一个进程可以由多个线程,例如在Windows系统中,xxx.exe就是一个进程。

线程:进程中的一个控制单元,负责当前进程中的程序执行,一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可以共享数据。

06、问:谈谈线程与进程的区别?

答:

根本区别

  • 进程是操作系统资源分配的基本单元,而线程是处理器任务调度的和执行的基本单位。

资源开销:

  • 每个进程都有自己独立的代码和空间(程序上下文),程序之间的切换会有较大的开销;线程可以看作轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

包含关系:

  • 如果一个进程内有多个线程,则执行的过程不是一条线的,而是多条线(多个线程),共同完成;线程是进程的一部分,可以把线程看作是轻量级的进程。

内存分配:

  • 同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的。

07、问:谈谈你对用户线程与守护线程的认识与理解

答:

  • 用户(User)线程:运行在前台,执行具体任务,如程序的主线程,连接网络的子线程都是用户线程。
  • 守护(Daemon)线程:运行在后台,为其它前台线程服务,也可以说守护线程是JVM非守护线程的”佣人“,一旦所有线程都执行结束,守护线程会随着JVM一起结束运行。

main函数就是一个用户线程,main函数启动时,同时JVM还启动了好多的守护线程,如垃圾回收线程,比较明显的区别时,用户线程结束,JVM退出,不管这个时候有没有守护线程的运行,都不会影响JVM的退出。

08、​​​​​​​问:什么是线程死锁呢?

答:死锁是指两个或两个以上进程(线程)在执行过程中,由于竞争资源或由于彼此通信造成的一种堵塞的现象,若无外力的作用下,都将无法推进,此时的系统处于死锁状态。

09、​​​​​​​问:请问形成死锁的必要条件?

答:

互斥条件:

  • 线程(进程)对所分配的资源具有排它性,即一个资源只能被一个进程占用,直到该进程被释放。

请求与保持条件:

  • 一个进程(线程)因请求被占有资源而发生堵塞时,对已获取的资源保持不放。

不剥夺条件:

  • 线程(进程)已获取的资源在未使用完之前不能被其他线程强行剥夺,只有等自己使用完才释放资源。

循环等待条件:

  • 当发生死锁时,所等待的线程(进程)必定形成一个环路,死循环造成永久堵塞。

10、问:请问如何避免死锁呢?

答:我们只需破坏形参死锁的四个必要条件之一即可。

破坏互斥条件:

  • 无法破坏,我们的锁本身就是来个线程(进程)来产生互斥

破坏请求与保持条件:

  • 一次申请所有资源

破坏不剥夺条件:

  • 占有部分资源的线程尝试申请其它资源,如果申请不到,可以主动释放它占有的资源。

破坏循环等待条件:

  • 按序来申请资源。

11、​​​​​​​问:什么是上下文的切换?

答:当前任务执行完,CPU时间片切换到另一个任务之前会保存自己的状态,以便下次再切换会这个任务时可以继续执行下去,任务从保存到再加载执行就是一次上下文切换。

12、问:请谈谈创建线程的几种方式

答:

  1. 继承Thread类

  2. 实现Runnable接口

  3. 实现Callable接口

  4. Executors工具类创建线程池

13、​​​​​​​问:Runnable接口和Callable接口有什么区别呢?

答:

相同点:Runnable和Callable都是接口、都可以编写多线程程序、都采用Thread.start()启动线程

不同点:

  • Runnable接口run方法无返回值,Callable接口call方法有返回值,是个泛型,和Futrue和FutureTask配合用来获取异步执行结果。
  • Runable接口run方法只能抛出运行时的异常,且无法捕获处理;Callable接口call方法允许抛出异常,可以获取异常信息。

注:Callable接口支持返回执行结果,需要调用FutureTask.get()得到,此方法会堵塞主线程继续往下执行,如果不调用就不会堵塞。

14、​​​​​​​问:run()方法和start()方法有什么区别吗?

答:

  • 每个线程都是通过某个特定的Thread对象对于的run()方法来完成其操作的,run方法称为线程体,通过调用Thread类的start方法来启动一个线程。
  • start()方法用于启动线程,run()方法用于执行线程的运行代码,run()可以反复调用,而start()方法只能被调用一次。
  • start()方法来启动一个线程,真正实现了多线程的运行。调用start()方法无需等待run()方法体代码执行结束,可以直接继续执行其它的代码;调用start()方法线程进入就绪状态,随时等该CPU的调度,然后可以通过Thread调用run()方法来让其进入运行状态,run()方法运行结束,此线程终止,然后CPU再调度其它线程。

15、​​​​​​​问:为什么调用start()方法会执行run()方法,为什么不能直接调用run()方法呢?

答:new Thread,线程进入了新建的状态,start方法的作用是使线程进入就绪的状态,当分配到时间片后就可以运行了。start方法会执行线程前的相应准备工作,然后在执行run方法运行线程体,这才是真正的多线程工作。

如果直接执行了run方法,run方法会被当作一个main线程下的普通方法执行,并不会在某个线程中去执行它,所以这并不是多线程工作。

总结:调用start方法启动线程可使线程进入就绪状态,等待运行;run方法只是thread的一个普通方法调用,还是在主线程里执行。

16、​​​​​​​问:请谈谈什么是Callable和Future?

答:

  • Callable接口也类似于Runnable接口,但是Runnable不会接收返回值,并且无法抛出返回结果的异常,而Callable功能更强大,被线程执行后,可有返回值,这个返回值可以被Future拿到,也就是说Future可以拿到异步执行任务的返回值。
  • Future接口表示异步任务,是一个可能没有完成的异步任务结果,所以说Callable用于产生结果,Future用于接收结果。

17、问:请谈谈什么是FutureTask?

答:FutureTask是一个异步运算的任务,FutureTask里面可以可以传入Callable实现类作为参数,可以对异步运算任务的结果进行等待获取,判断是否已经完成,取消任务等操作。只有当结果完成之后才能取出,如果尚未完成get方法将堵塞。一个Future对象可以调用Callable和Runable的对象进行包装,由于FutureTask也是Runnable接口的实现类,所以FutureTask也可以放入线程池中。


Thanks~

..

【问答篇】Java 线程篇 面试题(一)相关推荐

  1. 干货分享 JVM 之第 1 篇 —— Java 线程的重要知识点大全

    线程与进程区别 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理解为代码运行的上下文.所以线程基本上是轻量 ...

  2. 15个Java线程并发面试题和答案

    面试Java开发者时常问的15个Java多线程和并发问题 现在有线程 T1.T2 和 T3.你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行? 这个线程面试题通常在第一轮面 ...

  3. linux线程篇,linux线程篇 (二) 线程的基本操作

    线程 进程 标识符 pthread_t pid_t 获取ID pthread_self() getpid() 创建 pthread_create() fork 销毁 pthread_exit() ex ...

  4. 第三篇 Java 高级篇

    1.JVM内存分哪几个区,每个区的作用是什么?  java虚拟机主要分为以下几个区: (1)方法区: 有时候也成为永久代,在该区内很少发生垃圾回收,但是并不代表不发生GC,在这里进行的GC主要是对方法 ...

  5. java线程池 面试题(精简)

    什么是线程池? 线程池是一种多线程处理形式,处理过程中将任务提交到线程池,任务的执行交由线程池来管理. 如果每个请求都创建一个线程去处理,那么服务器的资源很快就会被耗尽,使用线程池可以减少创建和销毁线 ...

  6. Java线程专栏文章汇总(转)

    原文:http://blog.csdn.net/ghsau/article/details/17609747 JDK5.0之前传统线程        Java线程(一):线程安全与不安全 Java线程 ...

  7. java基础篇_java基础篇1

    JAVA基础篇1 注释 单行注释 //这是一个单行注释,由两个斜杠组成,不能嵌套多行注释 多行注释 /*这是一个 多行注释 ,//里面不能嵌套多行注释, 但是可以嵌套单行注释*/ 文档注释 /**ja ...

  8. java线程池面试题有哪些?java线程池常见面试题

    进行java面试的过程中,java线程池是必问的面试题目,因为这是java的重点知识,也是在java工作中经常会遇到的,那java线程池面试题有哪些?下面来我们就来给大家讲解一下java线程池常见面试 ...

  9. java线程协作_java线程系列之三(线程协作)

    上一篇讲述了线程的互斥(同步),但是在很多情况下,仅仅同步是不够的,还需要线程与线程协作(通信),生产者/消费者问题是一个经典的线程同步以及通信的案例.该问题描述了两个共享固定大小缓冲区的线程,即所谓 ...

最新文章

  1. AI研究生应届生年薪可达50万 没出校门已被抢光
  2. php连接mysql数据库测试_php连接mysql数据库连接测试文件
  3. IntelliJ IDEA 15快捷键大全
  4. 如何在SAP云平台Neo环境里进行workflow(工作流)的开发
  5. PHPmysqli的 预处理执行查询语句
  6. 【测试】模拟一个全表扫描的sql,对其进行优化走索引,并且将执行计划稳定到baseLine。...
  7. php查看mysql连接数_查看mysql当前连接数
  8. mysql配置文件参数详解 my.cnf
  9. Cellular Network
  10. uCOS-II的学习笔记(共九期)和例子(共六个)
  11. MYSQL 数据库配置优化
  12. excel多列合并关联数据
  13. stm32下OLED屏的应用
  14. python去除图片水印api_python opencv去图片水印
  15. 如何优雅使用JDK8中的Stream对list集合中的某值求和
  16. 保险产业拥抱“大数据时代” 或带来颠覆性变革
  17. 数组的应用和面向对象的开始6
  18. 超级解霸害死人——安装evc过程种出现“没有文件扩展.vbs的脚本引擎”的问题...
  19. Linux实战技巧--文件系统操作(五)--打包压缩和解压缩(tar)
  20. Bootstrap下拉菜单

热门文章

  1. java float小数点后几位小数_java实现double数据保留小数点后几位
  2. SQL无法修改数据类型-解决方法
  3. 项目质量管理---实施质量保证
  4. 爬虫基础:爬取百度贴吧-猫吧标题,详情页url,详情页图片url,下载图片
  5. 毕设路线—pytorch环境下的深度学习的高光谱图像分类问题
  6. php中怎么截取字符串最后一个字符,php如何取出字符串中的最后几个字符
  7. vmware 您的主机不满足在启用hyper-v或device/credential guard
  8. STM8S003F3 使用TIM1_CH1与TIM1_CH2配置PWM输出
  9. 从WGAN到WGAN-GP
  10. Install NVIDIA Drivers on Fedora 37