并发
为什么要并发? 比如因为IO操作遇到了阻塞,CPU可以转去执行其他线程,这时并发的优点就显示出来了:更高效的利用CPU,提高程序的响应速度。
Java的线程机制是抢占式的,会为每个线程分配时间片。
线程中断与上下文切换
并发编程 - 多线程的代价及上下文切换
上下文切换与多处理器
Java本身还有另外一个“线程中断”
基本的线程机制
使用Runnable和Thread创建线程:
Defining and Starting a Thread
“implements Runnable” vs. “extends Thread”
使用执行器Executor执行线程:
并发新特性—Executor框架与线程池(含代码)
Java线程(六):线程池
Interface Executor
让线程中的任务返回值:Callable
Java线程(七):Callable和Future
Java Callable Future Example
休眠sleep()、让步yield()
休眠(sleep)和让步(yield)会导致线程阻塞,CPU转而执行其他线程。对调用yield时,是在建议具有相同优先级的其他线程运行。
java之yield(),sleep(),wait()区别详解
线程优先级、后台线程
关于Java的Daemon线程的理解
JAVA并发编程——守护线程(Daemon Thread)
Java多线程系列–“基础篇”10之 线程优先级和守护线程
java 线程的优先级Priority
join()
简谈Java的join()方法
Java多线程中join方法的理解
捕获线程的异常
共享受限资源
synchronized
Java线程(二):线程同步synchronized和volatile
What does ‘synchronized’ mean?
重入锁ReentrantLock
Java线程(八):锁对象Lock-同步问题更完美的处理方式
Java 理论与实践: JDK 5.0 中更灵活、更具可伸缩性的锁定机制
锁
java锁的种类以及辨析(一):自旋锁
Java锁的种类以及辨析(二):自旋锁的其他种类
Java锁的种类以及辨析(三):阻塞锁
Java锁的种类以及辨析(四):可重入锁
Volatile变量
Java 理论与实践: 正确使用 Volatile 变量
聊聊并发(一)——深入分析Volatile的实现原理
CAS
原子类
Java 理论与实践: 流行的原子
Java多线程(二)之Atomic:原子变量与原子类
临界区(critical section)
线程本地存储ThreadLocal
Java线程(篇外篇):线程本地变量ThreadLocal
彻底理解ThreadLocal
Class ThreadLocal
Java ThreadLocal
When and how should I use a ThreadLocal variable?
终结任务
线程状态
一张图让你看懂JAVA线程间的状态转换
Life Cycle of Thread – Understanding Thread States in Java
Java 6 Thread States and Life Cycle
中断线程
详细分析Java中断机制
What does java.lang.Thread.interrupt() do?
如何停止线程
stop()方法已经被废弃了。
如何停止一个正在运行的java线程
How to stop a java thread gracefully?
线程协作
wait()、notify()、notifyAll()
阻塞是进程在等待某种资源,但是不能马上得到,必须等待别的进程释放资源才能继续,属于被动无法得到时间片,内核就切换其它进程运行
休眠一般为主动式的放弃一段CPU时间。
挂起是运行时间片到了,内核要调度其它进程运行,被动式的失去CPU。(挂起可以被别的进程给抢占导致挂起,也可以自己主动挂起自己。)
wait()会在等待时将当前任务挂起,等到notify()/notifyAll()发生时,任务才被唤醒。
调用sleep()、yield()时不会释放锁;调用wait()时线程被挂起,对象上的锁也会被释放。
wait()、notify()、notifyAll()属于类Object,不属于Thread。
只能在同步控制方法或者同步控制块(synchronized)中调用wait()、notify()、notifyAll()。而sleep()、yield()可以在非同步控制方法里使用。
notifyAll()比notify()更安全一些。使用notify()时,众多等待同一个锁的任务中只有一个会被唤醒。
Java Thread wait, notify and notifyAll Example
Lock和Condition
Java线程(九):Condition-线程通信更高效的方式
死锁
哲学家就餐问题
一个 Linux 上分析死锁的简单方法、死锁的4个必要条件
什么是死锁,死锁的四个必要条件以及处理死锁的策略
如何避免死锁
类库中的其他构件
CountDownLatch
CountDownLatch,闭锁。
首先给该对象一个初始计数值,每个在该该对象上调用await()的任务会阻塞。当计数值到0时,所有因为await()而阻塞的任务都继续执行。
Java CountDownLatch应用
CountDownLatch
Java多线程系列–“JUC锁”09之 CountDownLatch原理和示例
CyclicBarrier
CyclicBarrier,关卡,栅栏。
CountDownLatch和CyclicBarrier的区别
(01) CountDownLatch的作用是允许1或N个线程等待其他线程完成执行;而CyclicBarrier则是允许N个线程相互等待。
(02) CountDownLatch的计数器无法被重置;CyclicBarrier的计数器可以被重置后使用,因此它被称为是循环的barrier。
Java多线程系列–“JUC锁”10之 CyclicBarrier原理和示例
CyclicBarrier
BlockingQueue
Interface BlockingQueue
聊聊并发(七)——Java中的阻塞队列
DelayQueue
Examples of DelayQueue in Java
精巧好用的DelayQueue
Timer和TimerTask
这两个在java.util
这个包下面。
Timer和TimerTask可以做为实现线程的第三种方式,前两种方式分别是继承自Thread类和实现Runnable接口。
ScheduledThreadPoolExecutor
Java ScheduledThreadPoolExecutor延迟或周期性执行任务
Class ScheduledThreadPoolExecutor
信号量Semaphore
Java 信号量 Semaphore 介绍
Java Concurrency Tutorial – Semaphores
Exchanger
用于两个线程之间交换数据。
性能调优
使用Lock通常比sychronized高效,sychronized的开销看起来变化范围很大,Lock相对一致。synchronized产生的代码,与Lock所需要的“加锁-try/finally-解锁”相比,可读性更高。
CopyOnWriteArrayList、CopyOnWriteArraySet
在该类的对象中,写入将导致创建整个底层数组的副本,而原数组保留在原地,使得复制的数组在被修改时,读取操作可以安全的执行。当对副本的修改完成时,会发生一个原子性的操作:用副本替换源数组,使得新的读取操作可以看到这个新的修改。
Class CopyOnWriteArrayList
Java copy-on-write collections
Java多线程系列–“JUC集合”03之 CopyOnWriteArraySet
ConcurrentHashMap、ConcurrentLinkedQueue
聊聊并发(四)——深入分析ConcurrentHashMap
聊聊并发(六)——ConcurrentLinkedQueue的实现原理分析
Class ConcurrentHashMap
Class ConcurrentLinkedQueue
乐观锁
悲观锁与乐观锁
乐观并发控制
Concurrency control
Optimistic concurrency control
读写锁ReadWriteLock
适合读多写少的场景。
Java中的读/写锁
Java ReadWriteLock Example
ReadWriteLock
生产者消费者问题
其他
Java并发的四种风味:Thread、Executor、ForkJoin和Actor
Java Thread and Multithreading Tutorial
JAVA 多线程和并发基础面试问答
Java Multi-Threading and Concurrency Interview Questions with Answers
Monitor (synchronization)
聊聊并发