随着计算机行业的飞速发展,摩尔定律逐渐失效,多核 CPU 成为主流。使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器。J.U.C 提供的线程池:ThreadPoolExecutor 类,帮助开发人员管理线程并方便地执行并行任务。了解并合理使用线程池,是一个开发人员必修的基本功。

本文开篇简述线程池概念和用途,接着结合线程池的源码,帮助读者领略线程池的设计思路,最后回归实践,通过案例讲述使用线程池遇到的问题,并给出了一种动态化线程池解决方案。

一、前言

Java 提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自 JDK 8和 Netty 3.10.6)和使用场景进行举例,为读者介绍主流锁的知识点,以及不同的锁的适用场景。

Java 中往往是按照是否含有某一特性来定义锁,我们通过特性将锁进行分组归类,再使用对比的方式进行介绍,帮助大家更快捷的理解相关知识。下面给出本文内容的总体分类目录:

一、前言

1.1 文章起因

这篇文章的起因来源于一个 BUG,这个 BUG 和上篇文章《Java SynchronizedSet 线程不安全之坑》 有点关系。简单来说,就是在线程池中执行任务,任务本身未做异常处理,导致出现异常后任务停止。

出错的原因来自对 Collections.synchronizedSet(new HashSet<>()) 的线程不安全访问,抛出了 ConcurrentModificationException

问题的关键是在事后查询线上日志时并没有发现相关异常记录,导致问题的排查变得困难。所幸最后找到了问题,同时也发现了默认情况下线程中的异常是不会被记录到日志中的,也算是踩了个坑吧,这就是这篇文章的由来。

一、前言

一般而言,想要构造出线程安全的 Set,我们会使用 Collections.synchronizedSet 方法,如下所示。

Set<User> set = Collections.synchronizedSet(new HashSet<>());

但这并不意味着,你可以安全的使用该集合的任何方法,如果没有仔细的了解过其实现的话,一不小心就会踩进坑中。最近我在使用该集合的 stream 方法时发现了线程不安全问题,都是血的教训啊,下面写个Case 来复现下吧。

一、简介

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

在集合框架里,ArrayList 和 LinkedList 是使用最多的两种集合。ArrayList 和 ArrayBlockingQueue 一样,内部基于数组来存放元素,而 LinkedBlockingQueue 则和 LinkedList 一样,内部基于链表来存放元素。

LinkedBlockingQueue 实现了 BlockingQueue 接口,不同于 ArrayBlockingQueue,它如果不指定容量,容量默认为 Integer.MAX_VALUE,也就是无界队列

一、前言

今天来介绍下 concurrent 包下的一个工具类——CountDownLatch,这算是一个比较实用的工具类,在我们日常开发中使用的比较多,而且 API 也很简单,总结记录下。

二、基本使用

CountdownLatch 的主要功能是允许一个或多个线程等待直到在其他线程中一组操作执行完成,用人话说就是多个线程分别执行任务,另外某个线程等待这些线程全部执行完毕后,再做其他操作。

举个例子,麻麻在炒菜的时候,总是喜欢先将炒菜材料都准备好后,再准备开锅炒菜。由于今天家里来了客人,要准备的炒菜材料太多了,妈妈让你和你的弟弟一起来准备炒菜材料,麻麻等你们都准备好后开始炒菜。