关于程序员:面试重点建立Java并发知识体系含工具全图鉴

49次阅读

共计 3710 个字符,预计需要花费 10 分钟才能阅读完成。

大家好,我是悟空。先做个简略自我介绍:

硕士毕业于世界排名 Top9 的德国慕尼黑工业大学(计算机学科排名),国内毕业于同济大学,问题业余排名 Top1,获公派留学全额奖学金。现就职于一线明星互联网公司。

面试久了,你会发现 Java 并发编程 是面试的重点考察点。并且随着公司的倒退,用户量级会一劳永逸,高性能、高并发的问题天然防止不了,因而具备并发解决能力的 Java 程序员必然是宽广公司渴求的香饽饽。

接下来和大家分享我对 Java 并发常识的见解,全文次要分为如下 6 大点:

  1. Java 并发工具的痛点
  2. 三大类:线程平安、方便管理、互相配合
  3. 第一类:为了线程平安
  4. 第二类:为了治理线程
  5. 第三类:为了线程合作 – 管制并发流程的工具类
  6. 面试常见问题

1、Java 并发工具痛点

Java 并发中,一块十分重要的内容就是对于各种工具类的了解,常见的狭义的并发工具包含:线程池、ConcurrentHashMap、AtomicInteger、CopyOnWriteArrayList、ArrayBlockingQueue、synchronized、LongAdder、ThreadLocal、各种 Lock、Future、CountDownLatch、Semaphore 等等。

以上这些工具,大家或多或少必定都应用过,然而如果让咱们本人编写性能相似的工具类,就很容易出错,因为咱们可能会考虑不周;而 JDK 的常用工具类是通过了千万人测验的,值得信赖且功能完善。

咱们应该学会应用,并深刻了解这些工具类的原理。 非必须状况下,没有必要反复造轮子,因为如果让咱们本人写一个经得起考验的功能完善的线程池,那其实是十分艰难的,有几千行代码,实际上,能齐全读懂就曾经不太容易了。

从方才那一长串的工具类的名字中能够看出,并发工具的数量很多,而且性能如同也不尽相同,不容易齐全把握。

所以咱们在此,对 Java 中常见的工具类做一个梳理,把它们排排坐分分类,以便啃下这块“硬骨头”。

2、Java 工具三大类

Java 并发工具依照目标,一共分为 3 类:

  • 第一类:为了线程平安
  • 第二类:为了治理线程
  • 第三类:为了线程合作——管制并发流程

具体开展请点击下方的思维导图↓↓↓

有了这样的分类,将来咱们拿到一个不相熟的并发工具类的时候,就能够对号入座。先建设起全局的概念,将来的学习就会容易很多。

上面咱们对这三个类别别离开展形容。

3、第一类:为了线程平安

第一类是最常见的工具类,最典型的有各种锁、原子类、ConcurrentHashMap 等,这些工具的目标都是帮忙咱们在并发的状况下保障线程平安。

就达到线程平安的工具类而言,有两个分类的角度,第一个是从 底层原理 来分,第二个是从 使用者 程序员的角度来分类。这两种分类只是视角不同,然而实质雷同,是一一对应的关系。

在此,咱们以线程平安里的老大哥“锁”为例,来一探到底:

1. 锁的分类——各种类型的锁很多,乱花渐欲迷人眼,如何拨开迷雾,看透实质?

下图这些分类,是从各种不同角度登程去看的,然而这些分类并不是互斥的,也就是多个类型能够并存:有可能一个锁,同时属于两种类型,比方 ReentrantLock 既是互斥锁,又是可重入锁。

2. 常见的锁别离属于哪类?实用场景是什么?

能够看出,通常咱们把锁分为以下这些类别:

  1. 乐观锁和乐观锁
  2. 共享锁和独占锁
  3. 偏心锁和非偏心锁
  4. 可重入锁和非可重入锁
  5. 可中断锁和不可中断锁
  6. 自旋锁和非自旋锁

咱们以 3 个最罕用的锁为例子,剖析类型和实用场景如下:

4、第二类:为了治理线程

除了方才说到的为了线程平安的工具类之外,当初将要介绍的“治理线程”也是很重要的一类并发工具,最典型的就是线程池和 Future 相干类,咱们先来看看线程池。

为了方便管理线程,提高效率——线程池

1 线程池的重要性

线程池是十分重要的工具,如果你要成为一个好的工程师,须要比拟好地把握这个常识,很多线上问题都是因为没有用好线程池所导致的。

即便你现阶段的指标还未思考那么深远,也要晓得,这基本上是面试必问的题目,而且面试官很容易从被面试者的答复中捕捉到被面试者的技术水平。

2 什么是“池”

软件中的“池”,能够了解为工厂,工厂里有肯定数量的工人,工人会帮忙你制作产品,然而每一个工人的招聘和培训都要花费很大老本,所以你心愿尽量利用这已有的例如 20 个工人长期帮你做事,而不是每次都从新招聘。

如果最近生意好,咱们能够适当扩招,然而工厂所能被调配到的资源是无限的,比方占地面积、资金等,所以当你真的接到过多订单的时候,你没方法有限扩招工人,所以订单只能排队,期待工人缓缓解决。

总结成两点,“池”的作用:

  • 复用已有资源
  • 管制资源总量

数据库连接池是这样,线程池也是如此。

当一个新工作过去了,我发现池里有闲暇的线程,我就间接派他去干活,不须要从新创立一条线程了,要晓得线程的创立和销毁可都是麻烦事;而如果新工作过去的时候,如果池里的线程都在忙,并且当初池子的线程曾经很多了,那么新工作就去排队~

3 为什么要应用线程池

总而言之是减小开销,提高效率:

1) 问题一:重复创立线程开销大

在 Java 中,如果每个申请达到就去创立一个新线程,开销是相当大的,因为每一个 Java 的线程就对应一个操作系统的线程。

在理论应用中,线程的创立和销毁都是须要工夫的,如果是一个量级十分轻的申请,服务器也要新创建一条线程去解决,那么有可能创立和销毁线程耗费的工夫,比申请解决的工夫还更长。

2) 问题二:过多的线程会占用太多内存

创立过多的线程还会导致内存溢出。流动的线程须要耗费系统资源,如果在一个 JVM 里创立太多的线程,可能会使零碎因为适度耗费内存或“切换适度”而导致系统资源有余。

3) 解决以上两个问题的思路

尽可能应用大量的线程——防止内存占用过多

让这部分线程都放弃工作,且能够重复执行工作——防止生命周期的损耗

4 线程池益处
  • 线程池解决了线程生命周期开销问题和系统资源有余的问题

线程池刚创立的时候,会先创立肯定数量的线程,比如说 10 个,这样当有新申请调配过去的时候,就能够间接从池子里取出一个曾经创立好的线程,间接开始解决申请,这样就省去了创立线程的工夫。

再加上对线程的重复使用,就能够大大减小了线程生命周期的开销,而且因为在申请达到时线程曾经存在,所以打消了线程创立所带来的提早,应用应用程序响应更快,加强了用户体验。

  • 正当兼顾内存和 CPU 的应用

通过灵便适当地调整线程中的线程数目,使得既不会因为线程太多导致内存溢出(防止抛出 java.lang.OutOfMemoryError: unable to create new native thread),也不会因为线程太少导致节约 CPU 资源,而是能够达到完满的均衡。

  • 对立治理资源

应用线程池能够对立治理工作队列和线程,例如能够对立开始和完结,比单个线程逐个解决工作要更不便、更易于治理。同时这样也便于数据统计,因为每个 ThreadPoolExecutor 还保护一些根本统计数据,例如已实现工作的数量。

5 线程池适宜利用的场合

当一个服务器承受到大量短小线程的申请时,应用线程池技术是十分适合的,它能够大大减少线程的创立和销毁次数,进步服务器的工作效率。

获取子线程的运行后果——Future 相干类

Future 的核心思想是:一个办法的计算过程可能十分耗时,始终在原地期待办法返回,显然不明智。能够把该计算过程放到线程池去执行,并通过 Future 去管制办法的计算过程,在计算出后果后间接获取该后果,这样就防止了傻傻期待造成的工夫节约。

在 JDK 8 中,还引入了很好用的 CompletableFuture,能够实现例如“期待多个异步工作实现后,获取到后果,再利用这些后果执行接下来的工作”等更简单的性能。

5、第三类:为了线程合作

除了以上讲的“为了线程平安”、“为了治理线程”外,第三类并发工具类就是为了线程之间的合作互助。

管制并发流程的工具类,作用就是帮忙咱们程序员更容易得让线程之间发展单干,让线程之间相互配合,来满足业务逻辑,比方让线程 A 期待线程 B 执行结束后再执行工作等单干策略。

管制并发流程的工具类 简称同步工具类,次要有以下几个:

6、面试常见问题

对于 Java 并发工具类和原理,每一个类都有十分多的知识点将会作为面试时常见的问题。

在此咱们仅以 ConcurrentHashMap 为例,问题的难度会逐步增大:

· 比照 Hashtable, HashMap, TreeMap,它们有什么不同?

· 同样是线程平安,ConcurrentHashMap 和 Hashtable 的区别?

· 为什么有 Collections.synchronizedMap(),还须要 ConcurrentHashMap?

· HashMap(HashSet 同理)在多线程下可能造成 CPU100%,是为什么?

· JDK8 的 ConcurrentHashMap 也会造成 CPU 100%,你晓得吗?

· HashMap 在 Java 7 和 8 有什么不同?

· ConcurrentHashMap 在 Java 7 和 8 有什么不同?画一下结构图

· 为什么 Map 桶中超过 8 个才转为红黑树?

· ConcurrentHashMap 的扩容流程你理解吗?画一下流程图

作者 | 悟空 慕课网新星讲师

起源 | 慕课网(imooc.com)

本文由 mdnice 多平台公布

正文完
 0