当我刷到这条脉脉的时候,想到当年老板面试我的时候,拿多线程问题虐我时,想想当时太难了。 悄悄给大家看几道阿里必问的面试题,测测能完美的回答几道呢?

  1. 有没有一种一定能保证线程安全的代码写法?(偷偷告诉你,真的有!)

  2. 多个线程如何保持A1B2C3等顺序交替输出?

  3. synchronized volatile的CPU原语是如何实现的?

  4. 无锁、偏向锁、轻量级锁、重量级锁有什么差别?

  5. 如何正确的启动和停止一个线程?

  6. 线程和纤程的区别的是什么?为什么纤程比较轻量级?

  7. ThreadLocal有没有内存泄漏的问题?为什么?

  8. 下列三种业务,应该如何使用线程池:
    高并发、任务执行时间短
    并发不高、任务执行时间长
    并发高、业务执行时间长

前言

怎么样是不是感觉很难,而且现在毕业季快到了,不管是实习生还是有想要跳槽的大佬们即将进入找工作的高峰期,在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。

所以这篇文章是我最新整理的最全多线程并发面试47题和答案总结,希望对想进BAT的同学有帮助,由于篇幅较长,建议收藏后细看~

这些多线程的问题,有些来源于各大网站、有些来源于自己的思考。可能有些问题网上有、可能有些问题对应的答案也有、也可能有些各位网友也都看过,但是本文写作的重心就是所有的问题都会按照自己的理解回答一遍,不会去看网上的答案,因此可能有些问题讲的不对,能指正的希望大家不吝指教。

1、什么是线程安全和线程不安全?

通俗的说:加锁的就是是线程安全的,不加锁的就是是线程不安全的

线程安全
线程安全: 就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问,直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。

一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。很显然你可以将集合类分成两组,线程安全和非线程安全的。Vector 是用同步方法来实现线程安全的, 而和它相似的ArrayList不是线程安全的。

线程不安全

线程不安全:就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

2、什么是自旋锁?

基本概念
自旋锁是SMP架构中的一种low-level的同步机制。

当线程A想要获取一把自旋锁而该锁又被其它线程锁持有时,线程A会在一个循环中自旋以检测锁是不是已经可用了。

自旋锁需要注意:

  • 由于自旋时不释放CPU,因而持有自旋锁的线程应该尽快释放自旋锁,否则等待该自旋锁的线程会一直在那里自旋,这就会浪费CPU时间。
  • 持有自旋锁的线程在sleep之前应该释放自旋锁以便其它线程可以获得自旋锁。

实现自旋锁

一个简单的while就可以满足你的要求。

目前的JVM实现自旋会消耗CPU,如果长时间不调用doNotify方法,doWait方法会一直自旋,CPU会消耗太大。

public class MyWaitNotify3{MonitorObject myMonitorObject = new MonitorObject();boolean wasSignalled = false;public void doWait(){synchronized(myMonitorObject){while(!wasSignalled){try{myMonitorObject.wait();} catch(InterruptedException e){...}}//clear signal and continue running.wasSignalled = false;}}public void doNotify(){synchronized(myMonitorObject){wasSignalled = true;myMonitorObject.notify();}}
}

3、并发编程三要素?

1)原子性

原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行。

2)可见性

可见性指多个线程操作一个共享变量时,其中一个线程对变量进行修改后,其他线程可以立即看到修改的结果。

3)有序性

有序性,即程序的执行顺序按照代码的先后顺序来执行。

4、实现可见性的方法有哪些?

synchronized或者Lock:保证同一个时刻只有一个线程获取锁执行代码,锁释放之前把最新的值刷新到主内存,实现可见性。

5、多线程的价值?

1)发挥多核CPU的优势

多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的,采用多线程的方式去同时完成几件事情而不互相干扰。

2)防止阻塞

从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了。多线程可以防止这个问题,多条线程同时运行,哪怕一条线程的代码执行读取数据阻塞,也不会影响其它任务的执行。

3)便于建模

这是另外一个没有这么明显的优点了。假设有一个大的任务A,单线程编程,那么就要考虑很多,建立整个程序模型比较麻烦。但是如果把这个大的任务A分解成几个小任务,任务B、任务C、任务D,分别建立程序模型,并通过多线程分别运行这几个任务,那就简单很多了。

6、创建线程的有哪些方式?

1)继承Thread类创建线程类

2)通过Runnable接口创建线程类

3)通过Callable和Future创建线程

4)通过线程池创建

7、创建线程的三种方式的对比?

1)采用实现Runnable、Callable接口的方式创建多线程。

优势是:

线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。

在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。

劣势是:

编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

2)使用继承Thread类的方式创建多线程

优势是:

编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。

劣势是:

线程类已经继承了Thread类,所以不能再继承其他父类。

3)Runnable和Callable的区别

Callable规定(重写)的方法是call(),Runnable规定(重写)的方法是run()。
Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
Call方法可以抛出异常,run方法不可以。
运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

8、线程的状态流转图

线程的生命周期及五种基本状态:

9、Java线程具有五中基本状态

1)新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

2)就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

3)运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就
绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

4)阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。

根据阻塞产生的原因不同,阻塞状态又可以分为三种:

a.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

b.同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

c.其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

5)死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

10、什么是线程池?有哪几种创建方式?

线程池就是提前创建若干个线程,如果有任务需要处理,线程池里的线程就会处理任务,处理完之后线程并不会被销毁,而是等待下一个任务。由于创建和销毁线程都是消耗系统资源的,所以当你想要频繁的创建和销毁线程的时候就可以考虑使用线程池来提升系统的性能。

java 提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池。

11、四种线程池的创建:

1)newCachedThreadPool创建一个可缓存线程池

2)newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数。

3)newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

4)newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务。

12、线程池的优点?

1)重用存在的线程,减少对象创建销毁的开销。

2)可有效的控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。

3)提供定时执行、定期执行、单线程、并发数控制等功能。

由于篇幅不允许,所以下面只显示题目,然后需要多线程面试问题集锦(含答案)的文档可以点这里自行下载

13、常用的并发工具类有哪些?
14、CyclicBarrier和CountDownLatch的区别
15、synchronized的作用?
16、volatile关键字的作用
17、什么是CAS
18、CAS的问题
19、什么是Future?
20、什么是AQS
21、AQS支持两种同步方式:
22、ReadWriteLock是什么
23、FutureTask是什么
24、synchronized和ReentrantLock的区别
25、什么是乐观锁和悲观锁
26、线程B怎么知道线程A修改了变量
27、synchronized、volatile、CAS比较
28、sleep方法和wait方法有什么区别?
29、ThreadLocal是什么?有什么用?
30、为什么wait()方法和notify()/notifyAll()方法要在同步块中被调用
31、多线程同步有哪几种方法?
32、线程的调度策略
33、ConcurrentHashMap的并发度是什么
34、Linux环境下如何查找哪个线程使用CPU最长
35、Java死锁以及如何避免?
36、死锁的原因
37、怎么唤醒一个阻塞的线程
38、不可变对象对多线程有什么帮助
39、什么是多线程的上下文切换
40、如果你提交任务时,线程池队列已满,这时会发生什么
41、Java中用到的线程调度算法是什么
42、什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing)?
43、什么是自旋
44、Java
45、单例模式的线程安全性
46、Semaphore有什么作用
47、Executors类是什么?
48、线程类的构造方法、静态块是被哪个线程调用的
49、同步方法和同步块,哪个是更好的选择?
50、Java线程数过多会造成什么异常?

最后,小伙伴们一键三连呀

推荐阅读 《阿里p7的Java面试心路历程笔记,拿到了50w的Offer》 大家可以看一下这篇20000阅读量的文章,里面干货很多,如果你现在考虑跳槽或者将来准备面试千万不要错过它

想进一线大厂?2021年最详细Java多线程面试问题集锦(含答案),看完可以和面试官扯皮了!相关推荐

  1. 2020年Android开发年终总结之如何挤进一线大厂?(1),androidapp开发工具

    坚持写文章 坚持了ARTS打卡 坚持了每周的总结与下周规划 2021的展望 =============================== <Android学习笔记总结+最新移动架构视频+大厂安 ...

  2. 2020年中总结之 -- 怎么挤进一线大厂?非软文!

    文章目录 概述 阶段规划 如何走出小规模公司? 怎么进入中型公司? 怎么挤进一线大厂 进大厂需要如何准备 大厂面试通常会问答哪些问题呢?什么样的深度? 网络编程相关 java 集合 线程 算法 书籍/ ...

  3. 比尔盖茨离婚事件:给想进互联网大厂的人的唯一启示

    前几天的五四青年节,当今世界最富有的一对夫妇官宣离婚,瞬间登上热搜第一. 65岁的比尔盖茨和56岁的梅琳达,宣布结束27年的婚姻关系. 其中最让人感慨的是这样一句话: 我们不再相信在生命的下一段还能一 ...

  4. 想去一线大厂先过这一关, Java-SSM框架相关面试题整理!!!

    前言: 我们通常在面试的时候难免会慌张不已.想必,经历过的人都能体会.但是如果你提前预测和准备面试官要问你的问题,并想出合理的回答方式,就会轻松很多.所以接下来的面试题是我从自己和其他人的面试经历中总 ...

  5. 想进互联网大厂,该怎么做?

    近年来,互联网行业发展迅猛,不仅改变了我们的日常生活,也创造出了众多富豪.每一家互联网公司的上市,都会有一大批人实现财务自由. 与其他已经发展成熟的行业相比,互联网是机会最多的行业,再加上网上互联网大 ...

  6. 网络优化软件apk,金九银十怎么从中小企业挤进一线大厂?我先收藏为敬

    前言 从毕业到现在面试也就那么几家公司,单前几次都比较顺利,在面到第三家时都给到了我offer!前面两次找工作,没考虑到以后需要什么,自己的对未来的规划是什么,只要有份工作,工资符合自己的要求就行!所 ...

  7. Java并发编程实战_一线大厂架构师整理:java并发编程实践教程

    并发编程是Java语言的重要特性之一, 在Java平台上提供了许多基本的并发功能来辅助开发多线程应用程序.然而,这些相对底层的并发功能与上层应用程序的并发语义之间并不存在一种简单而直观的映射关系.因此 ...

  8. 2个字节能存多少个16进制_Java语言中最大的整数再加1等于多少?看完秒懂

    短文涨姿势,看了不白看,不关注等啥? 已知Java语言中int类型所能表示的最大整数为2147483647,请问以下代码执行结果是什么? 一部分人都会认为这段程序压根就无法通过编译,也有人认为,这段程 ...

  9. 1000道阿里巴巴初级~高级Java工程师面试题(含答案,2021最新华为Java校招面试题

    如何显示前50 行? 可以使用多少列创建索引? Now( )和CURRERT_DATE()有什么区别? 什么是非标准字符串类型? 什么是通用sQI函数? MySQL支持事务吗? MysQL里记录货币用 ...

最新文章

  1. iOS点滴- ViewController详解
  2. 浏览器渲染流水线解析
  3. 深入学习 History 对象管理浏览器会话历史
  4. secureCRT中文字符乱码
  5. 吃糖果(信息学奥赛一本通-T1193)
  6. www.android ind.com,Android
  7. Bzoj 4422: [Cerc2015]Cow Confinement(线段树+扫描线)
  8. 使用正当时!用扩展全面武装Firefox
  9. 怎样才能打开Tuxera NTFS的主界面?
  10. 滤波器原理及其作用计算机网络,滤波器的原理与作用
  11. java连接wamp_eclipse php wamp配置教程
  12. 滑动t检验在matlab上的实现
  13. 国内主要的PDM产品关于浏览圈阅模块的总结(2006)
  14. Google Earth Engine ——QGIS中计算加权质心
  15. 深度学习mindspore --- win10系统cpu下安装mindspore
  16. 移动电影院开启5G全新征程
  17. java:上传微信临时文件的素材
  18. 关于Openlayers Overlay事件监听的一个坑
  19. 硅谷AI商业化大会专题讨论:自动驾驶与智能交通的未来
  20. 程序员的自我修养—链接、装载与库 笔记

热门文章

  1. 起底百度内部架构调整,吴恩达和王劲的离开只是一个剪影
  2. Java+MySQL 基于springboot+vue的校园二手交易平台#毕业设计
  3. 粒子群算法的函数极值求解
  4. 偷偷爆料下2022年各公司年终奖情况,也就亿点点羡慕.....
  5. 中高级前端面试宝典之浏览器篇
  6. 用python写一个车牌号识别系统
  7. 51单片机入门教程学习笔记
  8. labelImg安装过程
  9. 删除包括:aux、lpt1、com1、com2的文件
  10. arm linux 安装 JRE