Java教程

【Java并发】Java并发编程-02

本文主要是介绍【Java并发】Java并发编程-02,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.Java并发包(JUC)

Java核心库的包

在这里插入图片描述

并发包分类

在这里插入图片描述

Java.util.concurrency

锁机制类 Locks : Lock, Condition, ReadWriteLock
原子操作类 Atomic : AtomicInteger
线程池相关类 Executer : Future, Callable, Executor
信号量三组工具类 Tools : CountDownLatch, CyclicBarrier, Semaphore
并发集合类 Collections : CopyOnWriteArrayList, ConcurrentMap

2.到底什么是锁

为什么需要显式的 Lock

回忆一下,上节课讲过的,
synchronized 可以加锁,
wait/notify 可以看做加锁和解锁。
那为什么还需要一个显式的锁呢?
synchronized 方式的问题:
1、同步块的阻塞无法中断(不能 Interruptibly)
2、同步块的阻塞无法控制超时(无法自动解锁)
3、同步块无法异步处理锁(即不能立即知道是否可以拿到锁)
4、同步块无法根据条件灵活的加锁解锁(即只能跟同步块范围一致)

更自由的锁

在这里插入图片描述

基础接口Lock

在这里插入图片描述

Lock示例

在这里插入图片描述

读写锁-接口与实现

在这里插入图片描述

基础接口-Condition

在这里插入图片描述

LockSupport-锁当前线程

在这里插入图片描述

用锁的最佳实践

Doug Lea《Java 并发编程:设计原则与模式》一书中,
推荐的三个用锁的最佳实践,它们分别是:

  1. 永远只在更新对象的成员变量时加锁
  2. 永远只在访问可变的成员变量时加锁
  3. 永远不在调用其他对象的方法时加锁
    KK总结-最小使用锁:
    1、降低锁范围:锁定代码的范围/作用域
    2、细分锁粒度:讲一个大锁,拆分成多个小锁

3.并发原子类

Atomic工具类

在这里插入图片描述

无锁技术-Atomic工具类

在这里插入图片描述

锁与无锁之争

  1. 思考一下,到底是有锁好,还是无锁好?
    什么情况下有锁好
    什么情况下无锁好
    乐观锁、悲观锁
    数据库事务锁
    CAS 本质上没有使用锁。
    并发压力跟锁性能的关系:
    1、压力非常小,性能本身要求就不高;
    2、压力一般的情况下,无锁更快,大部分都一次写入;
    3、压力非常大时,自旋导致重试过多,资源消耗很大。

LongAdder 对 AtomicLong 的改进

通过分段思想改进原子类,
大家想想,还有哪些是用这个思想?
多路归并的思想:

  • 快排
  • G1 GC
  • ConcurrentHashMap
    还记得我们讲的爬山,做一个大项目,都需要加里程碑,也是分段
    LongAdder 的改进思路:
    1、AtomicInteger 和 AtomicLong 里的 value 是所有
    线程竞争读写的热点数据;
    2、将单个 value 拆分成跟线程一样多的数组 Cell[]; 3、每个线程写自己的 Cell[i]++,最后对数组求和。

4.并发工具类详解

什么是并发工具类

思考一下:
多个线程之间怎么相互协作?
前面讲到的:
1、wait/notify,
2、Lock/Condition,
可以作为简单的协作机制。
但是更复杂的,需要这些线程
满足某些条件(数量,时间,)。
更复杂的应用场景,比如

  • 我们需要控制实际并发访问资源的并发数量
  • 我们需要多个线程在某个时间同时开始运行
  • 我们需要指定数量线程到达某个状态再继续处理

AQS

在这里插入图片描述

Semaphore 信号量

在这里插入图片描述

CountDownLatch

在这里插入图片描述

CyclicBarrier

在这里插入图片描述

CountDownLatch与CyclicBarrier比较

在这里插入图片描述

Future/FutureTask/CompletableFuture

在这里插入图片描述
在这里插入图片描述

CompletableFuture

在这里插入图片描述

这篇关于【Java并发】Java并发编程-02的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!