Java 线程池实现原理及其在美团业务中的实践

随着计算机行业的飞速发展,摩尔定律逐渐失效,多核 CPU 成为主流。使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器。J.U.C 提供的线程池:ThreadPoolExecutor 类,帮助开发人员管理线程并方便地执行并行任务。了解并合理使用线程池,是一个开发人员必修的基本功。 本文开篇简述线程池概念和用途,接着结合线程池的源码,帮助读者领略线程池的设计思路,最后回归实践,通过案例...

不可不说的 Java “锁”事

一、前言Java 提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自 JDK 8和 Netty 3.10.6)和使用场景进行举例,为读者介绍主流锁的知识点,以及不同的锁的适用场景。 Java 中往往是按照是否含有某一特性来定义锁,我们通过特性将锁进行分组归类,再使用对比的方式进行介绍,帮助大家更快捷的理解相关知识。下面给出...

Java 并发编程——线程池的异常处理机制

一、前言1.1 文章起因这篇文章的起因来源于一个 BUG,这个 BUG 和上篇文章《Java SynchronizedSet 线程不安全之坑》 有点关系。简单来说,就是在线程池中执行任务,任务本身未做异常处理,导致出现异常后任务停止。 出错的原因来自对 Collections.synchronizedSet(new HashSet<>()) 的线程不安全访问,抛出了 Concur...

Java SynchronizedSet 线程不安全之坑

一、前言一般而言,想要构造出线程安全的 Set,我们会使用 Collections.synchronizedSet 方法,如下所示。 Set<User> set = Collections.synchronizedSet(new HashSet<>()); 但这并不意味着,你可以安全的使用该集合的任何方法,如果没有仔细的了解过其实现的话,一不小心就会踩进坑中。最近我在...

为什么阿里巴巴要禁用 Executors 创建线程池?

一、写在前面通过阅读本篇文章你将了解到: 线程池的定义 Executors 创建线程池的几种方式 ThreadPoolExecutor 对象 线程池执行任务逻辑和线程池参数的关系 Executors 创建返回 ThreadPoolExecutor 对象 OOM 异常测试 如何定义线程池参数 二、线程池的定义管理一组工作线程。通过线程池复用线程有以下几点优点: 减少资源创建 => ...

Java-并发编程——CyclicBarrier

一、简介CyclicBarrier 是一个同步工具类,它允许一组线程在到达某个栅栏点(common barrier point)互相等待,发生阻塞,直到最后一个线程到达栅栏点,栅栏才会打开,处于阻塞状态的线程恢复继续执行.它非常适用于一组线程之间必需经常互相等待的情况。CyclicBarrier 字面理解是循环的栅栏,之所以称之为循环的是因为在等待线程释放后,该栅栏还可以复用。 建议阅读...

Java 并发编程——LinkedBlockingQueue

在集合框架里,ArrayList 和 LinkedList 是使用最多的两种集合。ArrayList 和 ArrayBlockingQueue 一样,内部基于数组来存放元素,而 LinkedBlockingQueue 则和 LinkedList 一样,内部基于链表来存放元素。 LinkedBlockingQueue 实现了 BlockingQueue 接口,不同于 ArrayBlocking...

Java 并发编程——ArrayBlockingQueue

一、简介ArrayBlockingQueue 顾名思义:基于数组的阻塞队列。数组是要指定长度的,所以使用 ArrayBlockingQueue 时必须指定长度,也就是它是一个有界队列。它实现了 BlockingQueue 接口,有着队列、集合以及阻塞队列的所有方法。 ArrayBlockingQueue 是线程安全的,内部使用 ReentrantLock 来保证。ArrayBlockin...

Java 并发编程——CountdownLatch

一、前言今天来介绍下 concurrent 包下的一个工具类——CountDownLatch,这算是一个比较实用的工具类,在我们日常开发中使用的比较多,而且 API 也很简单,总结记录下。 二、基本使用CountdownLatch 的主要功能是允许一个或多个线程等待直到在其他线程中一组操作执行完成,用人话说就是多个线程分别执行任务,另外某个线程等待这些线程全部执行完毕后,再做其他操作。 举个...

Java 并发编程——ReentrantLock

一、简介ReentrantLock 是一个可重入且独占式的锁,相较于传统的 Synchronized ,它增加了轮询、超时、中断等高级功能。其类图如下: ReentrantLock ReentrantLock 是 java.util.concurrent(J.U.C)包中的锁,相比于 synchronized,它多了以下高级功能: 1. 等待可中断 当持有锁的线程长期不释放锁的时候,正在等...

Java 并发编程——Thread 类的使用

在学习Thread类之前,先介绍与线程相关知识:线程的几种状态、上下文切换,然后接着介绍Thread类中的方法的具体使用。 一、线程的状态线程从创建到最终的消亡,要经历若干个状态。一般来说,线程包括以下这几个状态:创建(new)**、就绪(runnable)、运行(running)、阻塞(blocked)、time waiting、waiting、消亡(dead)**。 当需要新起一个线程来...

Java 并发编程——volatile 关键字解析

volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。 volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情。由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来...