JUC并发编程

一、JUC并发编程

1.1. 什么是JUC

1.1.1. 进程和线程、管程

  • 进程 -- 资源分配的最小单位

指在系统中正在运行的一个应用程序;程序一旦运行就是进程;每一个进程都有它自己的内存空间和系统资源。

  • 线程 -- 程序执行的最小单位

轻量级进程,系统分配处理器时间资源的基本单元,或者说进程之内独立执行的一个单元执行流。

  • 管程 -- Monitor,也就是我们平时所说的锁

一种同步机制,他保证(同一时间)只有一个线程可以访问被保护的数据和代码。

执行线程就要求先成功持有管程,然后才能执行方法,最后当方法完成(无论是正常完成还是非正常完成)时释放管程。在方法执行期间,执行线程持有了管程,其他任何线程都无法再获取到同一个管程。

1.1.2. 线程状态

  • NEW 新建
  • RUNNABLE 准备就绪
  • BLOCKED 阻塞
  • WAITING 不见不散
  • TIMED_WAITING 过时不候
  • TERMINATED 终结

1.1.3. wait和sleep的区别

  1. sleep 是 Thread 的静态方法,wait 是 Object 的方法,任何对象实例都能调用。
  2. sleep 不会释放锁,它也不需要占用锁。wait 会释放锁,但调用它的前提是当前线程占有锁(即代码要在 synchronized 中)。
  3. 它们都可以被 interrupted 方法中断。

1.1.4. 串行与并行

串行模式:

一次只能取得一个任务,并执行这个任务。

并行模式:

可以同时取得多个任务,并同时去执行这些任务。

1.1.5. 并发与并行

  • 并发:同一时刻多个线程在访问同一个资源,多个线程对一个点。
    • 例子:春运抢票 电商秒杀...
  • 并行:多项工作一起执行,之后再汇总。
    • 例子: 泡方便面,电水壶烧水,一边撕调料倒入桶中

1.1.6. 用户线程和守护线程

  • 用户线程
  1. 是系统的工作线程,它会完成这个程序需要完成的业务操作。
  • 守护线程
  1. 是一种特殊的线程为其它线程服务的,在后台默默地完成一些系统性的服务,比如垃圾回收线程就是最典型的例子。

  2. 守护线程作为一个服务线程,没有服务对象就没有必要继续运行了,如果用户线程全部结束了,意味着程序需要完成的业务操作已经结束了系统可以退出了。所以假如当系统只剩下守护线程的时候,java虚拟机会自动退出。

如果用户线程全部结束意味着程序需要完成的业务操作已经结束了,守护线程随着JVM一同结束工作。

setDaemon(true)方法必须在start()之前设置,否则报llegalThreadStateException异常。

1.2 CompletableFuture

1.2.1 Future接口

Future接口定义了操作 异步任务 执行一些方法,如获取异步任务的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕等。

1.2.2 Future接口优缺点

  • 优点
    future+线程池异步多线程任务配合,能显著提高程序的执行效率。

  • 缺点
    Future对于结果的获取不是很友好,只能通过阻塞或轮询的方式得到任务的结果。

阻塞方法:get()

在Future计算完成之前会一直处在阻塞状态下。

轮询:isDone()

容易耗费CPU资源

1.2.3 引入CompletableFuture

对于真正的异步处理我们希望是可以通过传入回调两数,在Future结束时自动调用该回调函数,这样,我们就不用等待结果。

CompletableFuture提供了一种观察者模式类似的机制,可以让任务执待完成后通知监听的一方。

1.2.4 CompletableFuture是什么

  • 在Java8中,CompletableFuture提供了非常强大的Future的广展功能,可以帮助我们简化异步编程的复杂性,并且提供了函数式编程的能力,可以通过回调的方式处理计算结果,也提供了转换和组合 CompletableFuture 的方法。
  • 它可能代表一个明确完成的Future,也有可能代表一个完成阶段(CompletionStage),它支持在计算完成以后触发一些函数或执行某些动作。
  • 它实现了Future和CompletionStaqe接口。

image

1.2.5 CompletionStage接口

  • CompletionStage代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段
  • 一个阶段的计算执行可以是一个Function, onsumer或者Runnable,比如: stage.thenApply(x -> square(x).thenAccept(x-> System.out.print(x)).thenRun(0 -> System.out.printIn0))
  • 一个阶段的执行可能是被单个阶段的完成触发,也可能是由多个阶段一起触发

1.2.6 CompletableFuture的优点

  • 异步任务结束时,会自动回调某个对象的方法;
  • 主线程设置好回调后,不再关心异步任务的执行,异步任务之间可以顺序执行;
  • 异步任务出错时,会自动回调某个对象的方法;

1.2.7 CompletableFuture四大核心方法

  • runAsync 无 返回值

    • public static CompletableFuture runAsync(Runnable runnable)
    • public static CompletableFuture runAsync(Runnable runnable,Executor executor)
  • supplyAsync有 返回值

    • public static<U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
    • public static<U> CompletableFuture<U> supplyAsync(Supplier<U> supplierExecutor executor)

没有指定Executor的方法,直接使用默认的ForkJoinPool.commonPool()作为它的线程池执行异步代码。

如果指定线程池,则使用我们自定义的或者特别指定的线程池执行异步代码

1.3 函数式编程

image

posted @ 2023-07-25 16:36  Pearl...T  阅读(8)  评论(0编辑  收藏  举报