跳至主要內容
AQS基础知识

一、简介

AbstractQueuedSynchronizer(简称AQS)是JAVA中一套实现锁机制的底层框架,Java中著名的JUC包的核心就是AQS框架。

AQS框架内部维护一个FIFO类型的Node队列来控制多线程的竞争排队顺序,使用一个int类型的state变量来定义当前共享资源占用的状态,定义了若干同步状态获取和释放的方法来供开发者使用,开发者只需要继承AbstractQueuedSynchronizer类,然后实现其中的指定模板方法,就可以快速实现一套线程同步控制组件。

AQS框架还定义了condition结构来提供线程的wait/signal(等待和唤醒)机制,同时根据资源互斥级别提供了独占锁/共享锁两种锁控制方式。


代码小郭...大约 14 分钟JAVA并发编程
并发编程中常用的工具类有哪些?

面试时经常会被问到:你了解哪些并发编程中的工具类?


上面的问题如果你答不上,我赌十包辣条,你这次面试肯定凉凉了。

对于JDK提供的并发编程工具,我们必须了解常见的几种:

  • 等待多线程完成的 CountDownLatch
  • 同步屏障 CyclicBarrier
  • 控制并发线程数的 Semaphore
  • 线程间交换数据的 Exchanger

代码小郭...大约 5 分钟JAVA并发编程
手写一个简单的线程池

一、废话少说,先上代码

下面代码实现了一个简单的,比较潦草的线程池~

1、定义线程池顶层接口

public interface ThreadPool<T> {
    // 执行一个 Job,这个 Job 需要实现 Runnable
    void execute(T job);
    // 关闭线程池
    void shutdown();
    // 增加工作者线程
    void addWorkers(int num);
    // 减少工作者线程
    void removeWorker(int num);
    // 得到正在等待执行的任务数量
    int getJobSize();
}

代码小郭...大约 8 分钟JAVA并发编程
多线程入门

一、理论基础

1、进程

简单来说,在系统中运行的一个应用程序就是一个进程,比如启动一个java程序,系统就会创建一个对应的进程。 每一个进程都拥有自己独立的内存空间和系统资源。

2、线程

线程(Light Weight Process)也称为轻量级线程,线程是大多数操作系统进行时间片分配调度的基本单元,是调度的最小单位。每一个进程下都至少有1个或多个线程,每个线程拥有独立的程序计数器、堆栈、局部变量等信息,并且能够访问共享变量。处理器在这些线程之间进行高速切换执行,让用户以为是在并发执行。

线程又可以分为用户线程和守护线程:


代码小郭...大约 18 分钟JAVA并发编程
synchronized关键字

一、简介

在多线程并发编程中 synchronized 是历史很悠久的概念,它可以用于修饰实例方法、静态方法、代码块。当一个线程试图访问同步代码时必须首先获得锁,正常退出或者抛出异常时必须释放锁。 由于会导致争用不到锁的线程进入阻塞状态,涉及到用户态和内核态的操作系统级别的切换动作,因此很多人都会称呼synchronized为重量级锁。

但是,随着 Java SE 1.5以后 对 synchronized 进行了各种优化之后,有些情况下它就并不那么重了。Java SE 1.6 中为了减少获得锁和释放锁带来的性能消耗而引入了无锁状态、偏向锁、轻量级锁、重量级锁、自旋等一系列锁升级概念。


代码小郭...大约 15 分钟JAVA并发编程
ThreadLocal的用法

一、原理

ThreadLocal(线程本地变量),是一个以 ThreadLocal 对象为键、任意对象为值的存储结构,底层是map键值对方式。

查看Thread类源码可以看到每个线程实例都会有自己的一个成员变量threadLocalMap:

ThreadLocal.ThreadLocalMap threadLocals = null;

代码小郭...大约 3 分钟JAVA并发编程
volatile关键字

一、简介

volatitle经常被用到并发编程的场景中。它的作用有两个,即:

  • 保证可见性;
  • 保证有序性。

但是,要注意volatile关键字并不能保证原子性。


二、如何保证可见性

由于每个线程都有自己的工作空间,导致多线程的场景下会出现缓存不一致性的问题。即,当两个线程共用一个共享变量时,如果其中一个线程修改了这个共享变量的值。但是由于另外一个线程在自己的工作内存中已经保留了一份该共享变量的副本,因此它无法感知该变量的值已经被修改。volatile可以解决这个问题。


代码小郭...大约 6 分钟JAVA并发编程
原子操作原来这么简单

一、什么是原子操作?

原子(atomic)含义是不能被进一步分割的最小粒子,而原子操作表示不可被中断的一个或一组操作。在多处理器上实现原子操作是很复杂的,一般是通过总线锁和缓存锁这两个机制来保证原子性。

我们可以通过synchronized来实现一个原子操作,但jdk1.5以后提供了专门的原子操作类,让我们可以安全的更新变量的值。

二、JDK中的原子操作类

在Java中是通过锁和循环CAS的方式来实现原子操作的。

JDK1.5的java.util.cconcurrent.atomic包里提供了很多原子操作类,比如AtomicBoolean、AtomicInteger、AtomicLong等,这些原子操作类基本都是使用 Unsafe 实现的包装类。


代码小郭...大约 8 分钟JAVA并发编程
锁的那些事

一、前言

多线程访问情况有三种:

  • 只有一个线程来访问
  • 有多个线程来访问(2个线程交替访问)
  • 并发量高,竞争激烈,多个线程来访问

多线程访问会涉及到线程安全问题,而锁可以用来解决这种并发访问导致的问题。

二、锁的常见分类



代码小郭...大约 11 分钟JAVA并发编程
Java中的阻塞队列

一、什么是阻塞队列?

阻塞队列科普

阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移除方法。

支持阻塞的插入方法:意思是当队列满时,队列会阻塞插入元素的线程,直到队列不满。

支持阻塞的移除方法:意思是在队列为空时,获取元素的线程会等待队列变为非空。

二、底层原理分析

首先说明,JAVA中的阻塞队列基本使用通知模式实现。


代码小郭...大约 12 分钟JAVA并发编程