Java 并发编程
Table of Contents
1 线程
1.1 线程六种状态
- NEW
- 线程对象刚创建,还未调用
Thread.start()
方法之前的状态
- 线程对象刚创建,还未调用
- RUNNALBE
- 线程调用
Thread.start()
方法过后,线程等待操作系统资源状态 - 该状态线程获取到操作系统资源后会立马执行
- 线程调用
- BLOCKED
- 线程执行状态被阻塞
- 线程进入 synchronized 代码块或 synchronized 方法时会出现 BLOCKED 状态
- 线程重入 synchronized 代码块或 synchronized 方法,调用
Object.wait()
方法也会进入阻塞状态
- WAITING
- 当前线程处于等待状态,等待其它线程释放资源
- 调用下来方法会进入等待状态
- 无超时版本的
Object.wait()
方法 - 无超时版本的
Thread.join()
方法 LockSupport.park()
- 无超时版本的
- TIMEDWAINTING
- 和 WAINTING 类似,只不过添加了超时
- 调用下来方法会进入超时等待状态
Thread.sleep()
- 超时版本的
Object.wait()
方法 - 超时版本的
Thread.join()
方法 LockSupport.parkNanos()
LockSupport.parkUntil()
- TERMINATED
- 线程结束
1.2 Thread
1.3 ThreadLocal
1.4 ThreadPoolExecutor
线程执行器,
2 线程死锁
2.1 死锁的四个必要条件
互斥条件
: 一个资源每次只能被一个进程使用请求与保持条件
: 一个进程因请求资源而阻塞时,对已获得的资源保持不放不剥夺条件
: 进程已获得的资源,在末使用完之前,不能强行剥夺循环等待条件
: 若干进程之间形成一种头尾相接的循环等待资源关系
3 CAS
4 AQS
5 核心组件
5.1 原子类
5.1.1 AtmoicInteger
5.1.2 AtomicReference
5.2 并发队列
5.2.1 LinkedBlockingQueue
5.2.2 ArrayBlockingQueue
5.2.3 ConcurrentLinkedDeque
5.2.4 ConcurrentLinkedQueue
5.3 同步工具
5.3.1 CountDownLatch
private static void doWork() { try { Thread.sleep(new Double(Math.random() * 3000).longValue()); } catch (InterruptedException e) { e.printStackTrace(); } } public static void test01() throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(5); for (int i = 0; i < 5; i++) { Thread t = new Thread( () -> { doWork(); countDownLatch.countDown(); // 不阻塞 System.out.printf("玩家[%s]准备就绪\n", Thread.currentThread().getName()); }); t.start(); } countDownLatch.await(); // 阻塞 System.out.println("游戏开始"); } public static void test02() throws InterruptedException { CyclicBarrier cyclicBarrier = new CyclicBarrier(5); for (int i = 0; i < 10; i++) { Thread t = new Thread( () -> { doWork(); try { System.out.printf("玩家[%s]选择英雄\n", Thread.currentThread().getName()); cyclicBarrier.await(); // 不阻塞,达到循环数字时所有线程同时唤醒,并循环利用 System.out.printf("玩家[%s]准备就绪\n", Thread.currentThread().getName()); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } }); t.start(); } }