随笔分类 - 并发编程
1
摘要:自JDK 1.5 开始,JDK提供了ScheduledThreadPoolExecutor类用于计划任务(又称定时任务),这个类有两个用途: 在给定的延迟之后运行任务 周期性重复执行任务 在这之前,是使用Timer类来完成定时任务的,但是Timer有缺陷: Timer是单线程模式; 如果在执行任务期
阅读全文
摘要:一、Java 8 Stream简介 从Java 8 开始,我们可以使用Stream接口以及lambda表达式进行“流式计算”。它可以让我们对集合的操作更加简洁、更加可读、更加高效。 Stream接口有非常多用于集合计算的方法,比如判空操作empty、过滤操作filter、求最max值、查找操作fin
阅读全文
摘要:一、什么是Fork/Join Fork/Join框架是一个实现了ExecutorService接口的多线程处理器,它专为那些可以通过递归分解成更细小的任务而设计,最大化的利用多核处理器来提高应用程序的性能。 与其他ExecutorService相关的实现相同的是,Fork/Join框架会将任务分配给
阅读全文
摘要:JDK中提供了一些工具类以供开发者使用。这样的话我们在遇到一些常见的应用场景时就可以使用这些工具类,而不用自己再重复造轮子了。 它们都在java.util.concurrent包下。先总体概括一下都有哪些工具类,它们有什么作用,然后再分别介绍它们的主要使用方法和原理。 类作用 Semaphore 限
阅读全文
摘要:16.1 什么是CopyOnWrite容器 在说到CopyOnWrite容器之前我们先来谈谈什么是CopyOnWrite机制,CopyOnWrite是计算机设计领域中的一种优化策略,也是一种在并发场景下常用的设计思想——写入时复制思想。 那什么是写入时复制思想呢?就是当有多个调用者同时去请求一个资源
阅读全文
摘要:一、同步容器与并发容器 我们知道在java.util包下提供了一些容器类,而Vector和HashTable是线程安全的容器类,但是这些容器实现同步的方式是通过对方法加锁(sychronized)方式实现的,这样读写均需要锁操作,导致性能低下。而即使是Vector这样线程安全的类,在面对多线程下的复
阅读全文
摘要:Java原生的锁——基于对象的锁,它一般是配合synchronized关键字来使用的。实际上,Java在java.util.concurrent.locks包下,还为我们提供了几个关于锁的类和接口。它们有更强大的功能或更高的性能。 一、synchronized的不足之处 我们先来看看synchron
阅读全文
摘要:一、阻塞队列的由来 我们假设一种场景,生产者一直生产资源,消费者一直消费资源,资源存储在一个缓冲池中,生产者将生产的资源存进缓冲池中,消费者从缓冲池中拿到资源进行消费,这就是大名鼎鼎的生产者-消费者模式。 该模式能够简化开发过程,一方面消除了生产者类与消费者类之间的代码依赖性,另一方面将生产数据的过
阅读全文
摘要:一、为什么要使用线程池 使用线程池主要有以下三个原因: 创建/销毁线程需要消耗系统资源,线程池可以复用已创建的线程。 控制并发的数量。并发数量过多,可能会导致资源消耗过多,从而造成服务器崩溃。(主要原因) 可以对线程做统一管理。 二、线程池的原理 Java中的线程池顶层接口是Executor接口,T
阅读全文
摘要:一、AQS简介 AQS是AbstractQueuedSynchronizer的简称,即抽象队列同步器,从字面意思上理解: 抽象:抽象类,只实现一些主要逻辑,有些方法由子类实现; 队列:使用先进先出(FIFO)队列存储数据; 同步:实现了同步的功能。 那AQS有什么用呢?AQS是一个用来构建锁和同步器
阅读全文
摘要:一、乐观锁与悲观锁的概念 锁可以从不同的角度分类。其中,乐观锁和悲观锁是一种分类方式。 悲观锁:悲观锁就是我们常说的锁。对于悲观锁来说,它总是认为每次访问共享资源时会发生冲突,所以必须对每次数据操作加上锁,以保证临界区的程序同一时间只能有一个线程在执行。 乐观锁:乐观锁又称为“无锁”,顾名思义,它是
阅读全文
摘要:首先需要明确的一点是:Java多线程的锁都是基于对象的,Java中的每一个对象都可以作为一个锁。还有一点需要注意的是,我们常听到的类锁其实也是对象锁。Java类只有一个Class对象(可以有多个实例对象,多个实例共享这个Class对象),而Class对象也是特殊的Java对象。所以我们常说的类锁,其
阅读全文
摘要:一、几个基本概念 在介绍volatile之前,我们先回顾及介绍几个基本的概念。 1.1、内存可见性 在Java内存模型那一章我们介绍了JMM有一个主内存,每个线程有自己私有的工作内存,工作内存中保存了一些变量在主内存的拷贝。内存可见性,指的是线程之间的可见性,当一个线程修改了共享变量时,另一个线程可
阅读全文
摘要:一、什么是重排序? 计算机在执行程序时,为了提高性能,编译器和处理器常常会对指令做重排序。 为什么指令重排序可以提高性能? 现在的CPU一般采用流水线来执行指令。简单地说,每一个指令都会包含多个步骤,每个步骤可能使用不同的硬件。因此,流水线技术产生了,流水线是并行的,多个指令可以同时处于同一个阶段,
阅读全文
摘要:一、并发编程模型 并发编程模型的两个关键问题 线程间如何通信?即:线程之间以何种机制来交换信息 线程间如何同步?即:线程以何种机制来控制不同线程间操作发生的相对顺序 有两种并发模型可以解决这两个问题: 消息传递并发模型 共享内存并发模型 这两种模型之间的区别如下表所示: 如何通信如何同步 消息传递并
阅读全文
摘要:合理的使用Java多线程可以更好地利用服务器资源。一般来讲,线程内部有自己私有的线程上下文,互不干扰。但是当我们需要多个线程之间相互协作的时候,就需要我们掌握Java线程的通信方式。下面将介绍Java线程之间的几种通信原理。 一、锁与同步 在Java中,锁的概念都是基于对象的,所以我们又经常称它为对
阅读全文
摘要:一、操作系统中的线程状态转换 首先我们来看看操作系统中的线程状态转换。在现在的操作系统中,线程是被视为轻量级进程的,所以操作系统线程的状态其实和操作系统进程的状态是一致的。 操作系统线程主要有以下三个状态: 就绪状态(ready):线程正在等待使用CPU,经调度程序调用之后可进入running状态。
阅读全文
摘要:一、线程组(ThreadGroup) Java中用ThreadGroup来表示线程组,我们可以使用线程组对线程进行批量控制。 ThreadGroup和Thread的关系就如同他们的字面意思一样简单粗暴,每个Thread必然存在于一个ThreadGroup中,Thread不能独立于ThreadGrou
阅读全文
摘要:一、Thread类和Runnable接口 首先,我们需要有一个“线程”类。JDK提供了Thread类和Runnable接口来让我们实现自己的“线程”类。 继承Thread类,并重写run方法; 实现Runnable接口的run方法; 1.1、继承Thread类 首先是继承Thread类 public
阅读全文
摘要:进程和线程的区别? 进程:是指运行中的应用程序,CPU进行分配资源的基本单位。 线程:是指进程中的一个执行流程,有时也成为执行场景。资源调度的基本单位,CPU执行的基本单位。 进程是一个个独立的运行环境,线程是在进程中执行的一个任务。他们两个本质区别是是否单独占有内存地址空间及其它系统资源。 一、进
阅读全文
1