转载

Java并发 -- 概述

  1. JUC中的 ExecutorFork/JoinFuture 本质上都是一种 分工 方法
  2. 并发编程领域还总结了一些 设计模式 ,基本上都是和 分工 方法相关
    Thread-Per-Message
    Worker Thread
    

同步

  1. 在并发编程领域里的 同步 ,主要指的就是 线程间的协作
    • 一个线程执行完了一个任务,如何通知执行后续任务的线程开始工作
  2. 协作一般是与分工相关的
    • JUC中的 ExecutorFork/JoinFuture 本质上都是一种 分工 方法
    • 但同时也能解决 线程协作 的问题
  3. 例如,用 Future 可以发起一个 异步 调用
    • 当主线程调用get()方法取结果时,主线程会等待
    • 当异步执行的结果返回时,get()方法就自动返回了
    • Future 工具类已经帮我们解决了 主线程和异步线程之间的协作
  4. JUC中的 CountDownLatchCyclicBarrierPhaserExchanger 都是用来解决 线程协作 问题的
  5. 但很多场景还是需要自己处理线程之间的协作,问题基本可以描述为
    • 当某个条件不满足时,线程需要等待,当某个条件满足时,线程需要被唤醒执行
  6. 在Java并发编程领域,解决 协作 问题的 核心技术管程 (Monitor)
    • 上面提到的所有线程协作技术 底层 都是利用 管程 来解决的
    • 管程是一种解决并发问题的 通用模型 ,除了能解决 线程协作 问题,还能解决 互斥 问题
    • 管程是解决并发问题的万能钥匙

互斥

  1. 分工和同步主要强调的是 性能 ,线程安全关注的是 并发程序的正确性
  2. 在并发程序里,当多个线程 同时访问 同一个共享变量时,结果是 不确定
    • 导致 不确定的主要源头可见性问题,有序性问题和原子性问题 ,为了解决这三个问题,Java引进来 Java内存模型
    • Java内存模型提供了一系列规则,可以避免可见性问题,有序性问题和原子性问题,但 不能完全解决线程安全的问题
  3. 解决 线程安全 问题的 核心方案 还是 互斥 ,互斥的定义: 在同一时刻,只允许一个线程访问共享变量
  4. 实现互斥的 核心技术synchronized 、JUC中的各种 Lock 都能解决互斥问题
  5. 锁解决了 线程安全 的问题,但同时也带来了 性能问题 ,可以针对场景进行优化
    • JUC中的 ReadWriteLockStampedLock 可以优化在 读多写少 的场景下锁的性能
    • 无锁的数据结构,例如JUC中的 原子类 都是基于 无锁 技术实现的
    • 使用 Copy-On-Write 模式
    • 不共享变量 (ThreadLocal)或者 变量只允许读 (final)
  6. 使用锁除了要注意性能之外,还需要注意 死锁 问题
原文  http://zhongmingmao.me/2019/04/10/java-concurrent-overview/
正文到此结束
Loading...