JUC并发编程

本文介绍了Java多线程的基础知识,包括并发与并行的区别,用户线程与守护线程的概念,以及线程的daemon属性。接着讨论了Future接口在异步计算中的作用,但其get()方法可能导致阻塞,而CompletableFuture作为Future的增强版,提供了非阻塞和函数式编程的能力。最后,文章探讨了乐观锁与悲观锁的策略,指出CAS算法在乐观锁中的应用。

一. 线程基础知识

1.Java多线程相关概念

(1) 1把锁synchronized

(2) 2个并

- 并发(concurrent)
	是在同一实体上的多个事件
	是在一台处理器上"同时"处理多个任务
	同一时刻,其实只有一个事件在发生
- 并行(parallel)
	是在不同实体上的多个事件
	是在多台处理器上同时处理多个任务
- 并发vs并行

(3) 3个程

- 进程:在系统中运行的一个应用程序就是一个进程,每一个进程都有它自己的内存空间和系统资源.
- 线程:也称为`轻量级进程`,在同一个进程内会有1个或多个线程,是大多数操作系统进行时序调度的基本单元.
- 管程: Monitor(监视器),也就是我们平时所说的锁 

2. 用户线程和守护线程

(1)Java线程分为用户线程和守护线程

- 一般情况下,`默认都是用户线程`
- 用户线程:是系统的工作线程,它会完成这个程序需要完成的业务操作
- 守护线程
	- 是一种特殊的线程`为其他线程服务的`,在后台默默完成一些系统性的服务,比如垃圾回收线程就是最典型的例子
	- 守护线程作为一个服务线程,没有服务对象就没有必要继续运行了.

(2) 线程的daemon属性

- true表示是守护线程
- false表示是用户线程 

(3)小总结

- 如果用户线程全部结束意味着程序需要完成的业务操作已经结束了,守护线程随着JVM一同结束工作
- setDaemon(true)方法必须在start()之前设置,否则报IllegalThreadStateException异常 

二 CompletableFuture

1. Future接口能干什么

Future接口可以为主线程开一个分支任务,专门为主线程处理耗时和费力的复杂任务.它提供了一种异步并行计算的功能

- 目的:异步多线程任务执行且返回有结果,三个特点:多线程/有返回/异步任务

2. Future接口常用实现类FutureTask异步任务

- 优点:future+线程池异步多线程配合,能显著提高程序的执行效率
- 缺点:
	- get()阻塞:一旦调用get()方法求结果,如果没有计算完成容易导致程序阻塞.
	- isDone()轮询:轮询的方式会耗费无谓的CPU资源,而且也不见得能及时地得到计算结果;
		- 如果想要异步获取结果,通常都会以轮询的方式去获取结果,尽量不要阻塞
	- Future对于结果的获取不是很友好,只能通过阻塞或轮询的方式得到任务的结果.
  • 想完成一些复杂的任务
- 对于简单的业务场景使用Future完全OK
- 回调通知
	- 应对Future的完成时间,完成了可以告诉我,也就是我们的回调通知
	- 通过轮询的方式去判断任务是否完成这样非常占CPU并且代码也不优雅
- 创建异步任务:Future+线程池配合
- 多个任务前后依赖可以组合处理 
	- 想将多个异步任务的计算结果组合起来,后一个异步任务的计算结果需要前一个异步任务的值
	- 将两个或多个异步计算合成一个一部计算,这几个异步计算互相独立,同时后面这个又依赖前一个处理的结果.
- 对计算速度选最快:当Future集合中某个任务最快结束时,返回结果,返回第一名处理
- Future能干的,CompletableFuture都能干

3.CompletableFuture对Future的改进

  • CompletableFuture为什么出现
    阻塞的方式和异步编程的设计理念相违背,而轮询的方式会耗费无谓的CPU资源
    JDK8设计出CompletableFuture,提供了一套观察者模式类似的机制,可以让任务执行完成后通知坚挺的一方.
  • CompletableFuture和CompletionStage源码分别介绍
    接口CompletionStage
    • CompletionStage代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另一个阶段,类似于Linux系统的管道分隔符传参数
      类CompletableFuture
    • CompletableFuture提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,并且提供了函数式编程的能力,可以通过回调的方式处理计算结果,也提供了转换和组合CompletableFuture的方法
    • 他可能代表一个明确完成的Future,也有可能代表一个完成阶段,它支持在计算完成以后触发一些函数或执行某些动作
    • 它实现了Future和CompletionStage接口
  • 核心的四个静态方法,来创建一个异步任务
- runAsync无返回值
- supplyAsync有返回值
- Executor executor参数说明:如果指定线程池,则使用我们自定义的或者特别指定的线程池执行异步代码
  • CompletableFuture的优点
- 异步任务结束后,会自动回调某个对象的方法
- 主线程设置好回调后,不再关心异步任务的执行,异步任务之间可以顺序执行
- 异步任务出错时,会自动回调某个对象的方法

4.从电商网站的比价需求说

  • 函数式编程已经主流
Lambda表达式+Stream流式调用+Chain链式调用+Java8函数式编程
	- Runnable
	- Function
	- Consumer
	- Supplier
  • 先说说join和get对比

5. CompletableFuture常用方法

  • 获得结果和触发计算
- 获取结果 
  • 对计算结果进行处理
  • 对计算结果进行消费
  • 对计算速度进行选用
  • 对计算结果进行合并

三、说说Java“锁”事

1. 从轻松的乐观锁和悲观锁开讲

- 悲观锁:认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改。
	- 适合写操作多的场景,先加锁可以保证写操作时数据正确
	- 显式的锁定之后再操作同步资源   (狼性锁)
- 乐观锁:认为自己在使用数据时`不会有别的线程修改数据或资源`,所以不会添加锁
	- 适合读操作多的场景,不加锁的特点能够使其读操作的性能大幅提升
	- 乐观锁则直接去操作同步资源,是一种无锁算法		(佛系锁)

synchronized关键字和Lock的实现类都是悲观锁
乐观锁最常用的是CAS算法,Java原子类中的递增操作就通过CAS自旋实现

2. 通过8种情况演示锁运行案例,看看我们到底锁的是什么

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值