Java面试题之线程

1. 进程和线程的区别

  1. 进程是资源分配的基本单位;线程是任务调度执行的基本单位;
  2. 进程的创建和销毁消耗的资源都比线程要多;
  3. 多个进程之间的内存资源是独立的;在一个进程中多个线程之间的内存资源是共享的;

一个进程中包含多个线程,一个线程中包含多个协程。在单线程中有多个协程并发执行,实际上还是串行执行的。

2. 并行和并发的区别

并行是在同一时刻内多条指令在多个处理器中执行,从微观和宏观上看都是并行的;

并发是在同一时刻内只能有一条指令执行,从宏观上是并行的,从微观上是串行的,只是把时间分成若干段,使每个进程之间快速交替执行。

3. Java 中怎么创建线程

  1. 继承 Thread 类,重写 run 方法(run中逻辑就是线程要执行的工作,只有当子类实例化,调用start方法时,才可以真正创建线程)
  2. 实现 Runnable 接口,重写 run 方法(创建了Runnable实例,将runnable实例作为参数传给线程,将线程要干的工作 和 线程本身 分开,使用Runnable来专门表示“线程要完成的工作”,这种方法的好处是,降低了耦合性,如果以后要修改代码,改动相对较少,只需要将修改后的Runnable传给其他的实体就可以了)
  3. 使用匿名内部类实现(创建Thread子类的方式或实现Runnable接口的方法)
  4. 实现 Callable 接口,并结合 Future 实现(很少用)
  5. 通过线程池创建线程(创建 Runnable 的实现类,重写 run 方法,然后创建一个拥有固定线程数的线程池,最后通过 ExecutorService 对象的 execute 方法传入线程对象)

4. 常见操作线程的方法

  1. 启动线程:start
  2. 中断线程:isInterrupted(线程中断,本质上是让run方法尽快结束,而不是run执行一半,强制结束)
  3. 等待线程:join
  4. 获取当前线程引用:currentThread();   获取到当前这个线程对应的Thread对象的引用

5. 线程状态

新建(new)-就绪(runnable)-运行(running)-阻塞(block)-死亡(dead

  1. new:安排了工作,还未开始行动(Thread对象创建完成,但内核PCB还没创建);
  2. runnable:可工作的,又可以分成正在工作(正在CPU上运行)和即将开始工作(就绪状态:在就绪队列中排队)
  3. blocked:等待状态(等待锁的时候进入阻塞状态Synchronized)
  4. waiting:等待状态(特殊的阻塞状态,调用wait)
  5. timed_waiting:等待状态(按照一定的时间进行阻塞Sleep)
  6. terminated:工作完成(内核PCB销毁,但是Tread对象还在)

6. 线程不安全的原因

  1. 操作系统调度执行的随机性,抢占式执行
  2. 多个线程修改同一个变量
  3. 修改操作不是原子的(解决线程安全最常见的方法:加锁Synchronized)
  4. 内存可见性(内存可见性属于是JVM的代码优化引入的bug)
  5. 指令重排序

7.  Synchronized 和 ReentrantLock 的区别

  1. 用法不同,Synchronized 可以用来修饰普通方法、静态方法和代码块,而 ReentrantLock 只能用于代码块;
  2. 锁类型不同,Synchronized 是非公平锁,而 ReentrantLock 默认为非公平锁,也可以手动指定为公平锁(构造时传入一个参数true,就成了公平锁)
  3. 获取锁和释放锁的机制不同:synchronized是自动加锁和释放锁的(搭配 wait/ notify 实现等待通知机制,唤醒操作时随机唤醒一个等待进程),而 ReentrantLock 需要手动加锁和释放锁(tryLock试试加锁能不能成功,如果失败了,就等待一定时间后就放弃加锁。使用Condition可以将唤醒操作指定唤醒哪个等待的线程的)
  4. 响应时间不同:ReentrantLock 可以响应中断(加超时时间),解决死锁问题,而 synchronized 不能响应中断
  5. 底层实现不同:synchroized 是JVM 层面通过监视器实现的,而 ReentrantLock 是基于AQS 实现的

8. Volatile 是什么

volatile 是一种关键字,用于保证多线程情况下共享变量的可见性。当一个变量被声明为 volatile 时,每个线程在访问该变量时都会立即刷新其本地内存(工作内存)中该变量的值,确保所有线程都能读到最新的值。并且使用 volatile 可以禁止指令重排序,这样就能有效的预防,因为指令优化(重排序)而导致的线程安全问题。

也就是说 volatile 有两个主要功能:保证内存可见性和禁止指令重排序。

9. wait 和 notify 的作用

作用:协调多个线程的执行顺序

wait操作本质上三步走

(1)释放当前锁,保证其他线程能够正常往下进行(前提是得加了锁。才能释放)

(2)进行等待通知(前提是先要释放锁)

(3)满足一定条件的时候(别的线程调用notify),被唤醒,然后尝试重新获取锁

notify是包含在synchronized里面的

线程1没有释放锁的话,线程2也就无法调用到notify(因为锁阻塞等待)

线程1调用wait,在wait里面就释放了锁,这个时候虽然线程1代码阻塞在synchronized里面

但是此时锁还是释放状态,线程2能拿到锁

10. 线程池怎么创建,里面的参数都有啥

使用标准库中的线程池 ExecutorService,里面的参数都有:

  1. 核心线程数(corePoolSize):相当于正式工,只要核心线程创建好后,就不会被回收,也就是核心线程数不变

  2. 最大线程数(maximumPoolSize):相当于正式工+临时工,任务多的时候,正式工忙不过来(核心线程数已满),就多招几个临时工,这个是动态调整的;

  3. 空闲线程存活时间(KeepAliveTime):线程等待新任务的最大时间

  4. 空闲线程存活时间单位(unit):时间单位

  5. 任务队列(workQueue):队列中存放当前等待要执行的任务,任务队列有4中:

    • ArrayBlockingQueue:基于数组的有界阻塞队列;

    • LinkedBlockingQueue:基于链表的无界阻塞队列:

    • SynchronizedQueue:加锁后的队列,也就是不缓存任务的阻塞队列;

    • PriorityBlockingQueue:优先级的无界阻塞队列;

  6. 线程的创建策略(threadFactory):创建一个新线程时使用的工厂,可以用来设定线程名等

  7. 线程池的拒绝策略(handler):表示当队列慢了并且工作线程>= 线程池最大线程数时如何处理

    • AbortPolicy:丢弃任务并抛出异常;

    • DiscardPolicy:丢弃任务,但不抛出异常;

    • DiscardOldestPolicy:丢弃队列中最前面的任务,然后重新提交被拒绝的任务。

    • CallerRunsPolicy:由调用线程处理该任务;

11. 线程池的优点

(1)降低资源消耗:通过重复利用已创建的线程来执行任务,降低线程创建和消耗造成的消耗

(2)提高响应速度:因为省去了创建线程这一步,所以当拿到任务时,可以立即开始执行

(3)提高线程的可管理性:我们可以自己加入新的功能,比如说定时、延时来执行某些线程,也可以监控线程,控制最大并发线程数等功能

12. 说一下死锁的概念

死锁就是,一个线程加上锁之后,解不开了,一直在等待着。

多个线程被同时阻塞了,它们中个一个或多个线程都在等待某个资源被释放。由于线程被无期限的阻塞,因此程序不能正常终止。

发生死锁的四个条件:

不可抢占、请求和保持、互斥使用、循环等待

这里有一个死锁的经典模型就是哲学家就餐问题。

12. 常见的锁策略

http://t.csdnimg.cn/Z9eAf

13. 线程池如何执行?拒绝策略有哪些

线程池的执行流程有 3 个重要的判断点(判断顺序依次往后):判断当前线程数和核心线程数、判断当前任务队列是否已满、判断当前线程数是否已达到最大线程数。如果经过以上 3 个判断,得到的结果都会 true,则会执行线程池的拒绝策略。

 

当任务过多且线程池的任务队列已满时,此时就会执行线程池的拒绝策略,线程池的拒绝策略默认有以下 4 种:

  1. AbortPolicy:中止策略,线程池会抛出异常并中止执行此任务;
  2. CallerRunsPolicy:把任务交给添加此任务的(main)线程来执行;
  3. DiscardPolicy:忽略此任务,忽略最新的一个任务;
  4. DiscardOldestPolicy:忽略最早的任务,最先加入队列的任务。

默认的拒绝策略为 AbortPolicy 中止策略。

14. 线程池的底层工作原理

线程池的底层是基于线程和任务队列来实现的,创建线程池的创建方式通常有以下两种:

  1. 普通 Java 项目,使用 ThreadPoolExecutor 来创建线程池(ExecutorService)
  2. Spring 项目中,会使用代码可读性更高的 ThreadPoolTaskExecutor 来创建线程池,虽然它的底层也是通过 ThreadPoolExecutor 来实现的,但 ThreadPoolTaskExecutor 可读性更高,因为它不需要在构造方法中设置参数,而是通过属性设置的方式来设置参数的,所以可读性更高。

15.  什么是CAS

CAS(比较并交换)是一种轻量级的同步操作,也是乐观锁的一种实现,它用于实现多线程环境下的并发算法。CAS 操作包含三个操作数:内存位置(或者说是一个变量的引用)、预期的值和新值。如果内存位置的值和预期值相等,那么处理器会自动将该位置的值更新为新值,否则不进行任何操作。

16. 什么是 ABA 问题如何解决

http://t.csdnimg.cn/GDVz6

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/537735.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌蓝牙快速配对(GFPS)技术规范及认证资讯

蓝牙作为短距离传输的主力之一,应用的场景非常广泛,故多个联盟或超级企业在制定标准时,无论是从协议对接、使用场景规范,还是应用要求,都会充分考虑蓝牙的重要作用性,Google也不例外。 今天众乐认证就详细…

信息收集:端口扫描原理,端口扫描分类,端口扫描工具,手动判断操作系统,操作系统识别工具

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「专栏简介」:此文章已录入专栏《网络安全自学教程》 端口&系统版本 一、端口扫描1、telnet2、Nmap3、Masscan4、端口扫描原…

腾讯云学生服务器购买方法_学生购买腾讯云这样才便宜!

腾讯云学生服务器优惠活动「云校园」轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年,轻量应用服务器4核8G配置112元3个月、352.8元6个月、646.8元一年,CVM云服务器2核4G3M公网带宽配置842.4元一年,腾讯云服务器网txyfwq.com分享2…

5.Python从入门到精通—Python 运算符

5.Python从入门到精通—Python 运算符 Python 运算符算术运算符比较(关系)运算符赋值运算符逻辑运算符位运算符成员运算符身份运算符运算符优先级 Python 运算符 Python语言支持以下类型的运算符: 算术运算符比较(关系)运算符赋…

【消息队列开发】实现DataBaseManagerTests(测试单元)

文章目录 🍃前言🌳准备工作🎍书写测试代码⭕总结 🍃前言 今天我们来对前面所开发的数据库操作的功能进行测试一下 🌳准备工作 由于我们接下来要写很多测试用例 并且我们希望每个方法都是一个/一组单元测试用例&am…

0基础转行软件测试?需要做哪些准备?

一说到软件测试,可能会有很多朋友会问:软件行业如何?行业背景到底是怎么样的?以后发展前景好吗?今天我就给大家做一个深度剖析,到底做软件行业好不好?有什么优势?软件测试对学历有什…

【掌握版本控制:Git 入门与实践指南】多人协作

🎬慕斯主页:修仙—别有洞天 ♈️今日夜电波:泥中に咲く—ウォルピスカーター 0:34━━━━━━️💟──────── 4:46 🔄 ◀️ ⏸ ▶…

搭建个人智能家居 3 -第一个设备“点灯”

搭建个人智能家居 3 -第一个外设“点灯” 前言ESPHome点灯 HomeAssistant 前言 前面我们已经完成了搭建这个智能家居所需要的环境HomeAssistant和ESPHome,今天我们开始在这个智能家居中添加我们的第一个设备(一颗LED灯),如果环境…

SpringBoot(静态资源访问+Rest风格请求)

文章目录 1.静态资源访问1.基本介绍2.快速入门1.新建一个maven项目2.引入依赖 pom.xml3.创建文件目录4.Application.java5.创建四个可以存放静态资源的文件夹6.通过浏览器访问(这四个都可以访问) 3.注意事项和细节1.关于静态资源的访问管理2.修改静态资源…

小迪安全40WEB 攻防-通用漏洞CSRFSSRF代码审计同源策略加载函数

#知识点: 逻辑漏洞 1、CSRF-原理&危害&探针&利用等 2、SSRF-原理&危害&探针&利用等 3、CSRF&SSRF-黑盒下漏洞探针点 #详细点: CSRF 全称:Cross-site request forgery,即,跨站请求…

Python AI 之Stable-Diffusion-WebUI

Stable-Diffusion-WebUI简介 通过Gradio库,实现Stable Diffusion web 管理接口 Windows 11 安装Stable-Diffusion-WebUI 个人认为Stable-Diffusion-WebUI 官网提供的代码安装手册/自动安装不适合新手安装,我这边将一步步讲述我是如何搭建Python Conda…

【linux本地安装tinycudann包教程】

【linux本地安装tinycudann包教程】 tiny-cuda-nn官网链接 如果你是windows 10系统的,想要安装tiny-cuda-nn可以参考我的文章——windows 10安装tiny-cuda-n包 根据官网要求:C++要求对应14,其实这样就已经告诉我们linux系统中的gcc版本不能高于9,同时下面又告诉我们gcc版…