前言

可以将Java并发编程抽象为三个核心问题:分工、同步和互斥。
这三个问题的产生源自对性能的需求。最初时,为提高计算机的效率,当IO在等待时不让CPU空闲,于是就出现了分时操作系统也就出现了并发。后来,多核CPU出现,不同的任务可以同时独立运行,于是就出现了并行【分工】。有了分工后,效率得到了很大的提升,但是为了更合理的安排以及控制任务的进行,就需要让进程之间可以通信【同步】,让彼此知道进度的执行。分工进行提高了效率,但是却带来了多线程访问共享资源会冲突的问题。于是对共享资源的访问又需要串行化。所以,依据现实世界的做法设计了锁等机制来使得多线程【互斥】访问共享资源。

分工(性能)

分工的主要工作是:如何高效拆解任务并分配给线程。   

Java SDK并发包中的ExecutorFork/JoinFuture本质上都是分工方法。
并发编程中的一些设计模型也是指导如何分工:生产者——消费者Thread-Per-MessageWork Thread等。

 同步(性能)

在并发编程的同步,主要指的就是线程间的协作。即当一个线程执行完了,该如何通知后续任务的线程展开工作。

协作一般和分工相关。Java SDK中ExecutorFork/JoinFuture本质上是分工方法但是也解决线程之间的协作问题(如Future异步调用,get())。Java SDK里提供的CountDownLatchCyclicBarrierPhaserExchanger也是用于解决线程之间的协作问题。

线程协作问题都可以被描述为:当某个条件不满足时,线程需要等待,当某个条件满足使,线程需要被唤醒执行

互斥(正确性/线程安全)

互斥指的是:在同一时刻,只允许一个线程访问共享变量。

因为 可见性有序性原子性(后面会有文章介绍)问题,多个线程访问同一个共享变量会导致结果的不确定 。
为了解决这三个问题,Java语言引入了内存模型,内存模型提供了一系列的规则,利用这些规则我们可以避免可见性问题、有序性问题,但是还不能完全解决线程安全问题。

解决线程安全问题的核心方案还是互斥

实现互斥的核心技术就是锁。 Java语言中synchronized、SDK中的各种Lock都可以解决互斥问题,但是锁却会带来性能问题,于是我们就需要平衡。

主要方案有:分场景优化,优化读多写少场景:ReadWriteLockStampledLock以及无锁结构Java SDK中的原子类;其他方案,原理为不共享变量或者变量只允许读,Java中提供了Thread LocalFinal关键字和Copy-on-write 模式。

小结

在看极客时间专栏《Java并发编程实战》学习攻略时,感触还是比较深。平时学习知识都是“独立”的,没有一种“全局”观念,也很少联系其他一些理论来侧面验证学习的知识,导致学过后就很容易忘记。看了这篇专栏前言后,总结出:学习知识时,要跳出来看全景,钻进去看本质。要知道每一种技术背后都应该有理论支持,并且这个理论可能是跨领域的,所以,掌握技术背后的理论十分很重要!
针对Java并发编程应该要结合操作系统一起来学习,如后面将要介绍的可见性、有序性和原子性。理解可见性就需要了解CPU和缓存的知识;理解原子性就需要理解操作系统的知识;很多无锁算法也是和CPU缓存有关。要联系起CPU、内存、I/O之间的关系。

参考:
[1]极客时间专栏王宝令《Java并发编程实战》

【Java并发基础】并发编程领域的三个问题:分工、同步和互斥的更多相关文章

  1. 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

    Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)   介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...

  2. Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

    介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可以看作是Unix进程的表亲,同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间, ...

  3. Java之基础(1) - 编程中“为了性能”尽量要做到的一些地方

    最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Ja ...

  4. java 25 - 2 网络编程之 网络通信三要素

    网络通信三要素 IP地址: InetAddress 网络中设备的标识,不易记忆,可用主机名(计算机的标识号) 端口号: 用于标识进程的逻辑地址,不同进程的标识(正在运行的软件的标识号) 传输协议: 通 ...

  5. java并发编程笔记(三)——线程安全性

    java并发编程笔记(三)--线程安全性 线程安全性: ​ 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现 ...

  6. 【Java并发基础】利用面向对象的思想写好并发程序

    前言 下面简单总结学习Java并发的笔记,关于如何利用面向对象思想写好并发程序的建议.面向对象的思想和并发编程属于两个领域,但是在Java中这两个领域却可以融合到一起.在Java语言中,面向对象编程的 ...

  7. 艾编程coding老师课堂笔记:java设计模式与并发编程笔记

    设计模式概念 1.1 什么是设计模式 设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路.它不是语法规定,而是一套用来提高代码可复用性.可维护性.可读性. ...

  8. Java 并发基础

    Java 并发基础 标签 : Java基础 线程简述 线程是进程的执行部分,用来完成一定的任务; 线程拥有自己的堆栈,程序计数器和自己的局部变量,但不拥有系统资源, 他与其他线程共享父进程的共享资源及 ...

  9. Java并发基础:进程和线程之由来

    转载自:http://www.cnblogs.com/dolphin0520/p/3910667.html 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程. ...

随机推荐

  1. JS精度问题,解决方案 math.js

    JS精度问题    Vue中使用 解决方案 math.js npm install mathjs import { create, all } from 'mathjs' const config = ...

  2. java Set接口(元素不可以重复)

    Set是Collection子接口: Set和Collection基本上一样,一点除外: Set无法记住添加的顺序,不允许包含重复的元素. 当试图添加两个相同元素进Set集合,添加操作失败,add() ...

  3. H3C TFTP协议介绍

  4. I/O 端口和 I/O 内存

    每个外设都是通过读写它的寄存器来控制. 大部分时间一个设备有几个寄存器, 并且在连 续地址存取它们, 或者在内存地址空间或者在 I/O 地址空间. 在硬件级别上, 内存区和 I/O 区域没有概念上的区 ...

  5. 2018-11-5-win10-uwp-异步转同步

    title author date CreateTime categories win10 uwp 异步转同步 lindexi 2018-11-05 10:18:40 +0800 2018-2-13 ...

  6. Linux 内核 /sys/class类

    我们在本章中要考察最后的设备模型概念是类.一个类是一个设备的高级视图, 它抽象出 低级的实现细节. 驱动可以见到一个 SCSI 磁盘或者一个 ATA 磁盘, 在类的级别, 它们都 是磁盘. 类允许用户 ...

  7. Linux 内核列举设备和驱动

    如果你在编写总线级别的代码, 你可能不得不对所有已经注册到你的总线的设备或驱动进 行一些操作. 它可能会诱惑人直接进入 bus_type 结构中的各种结构, 但是最好使用已经 提供的帮助函数. 为操作 ...

  8. Kobjects, Ksets 和 Subsystems

    Kobject 是基础的结构, 它保持设备模型在一起. 初始地它被作为一个简单的引用计数, 但是它的责任已随时间增长, 并且因此有了它自己的战场. struct kobject 所处理的任 务和它的支 ...

  9. vue-learning:22 - js - directives

    directives 在讲解视图层指令时,我们讲到ref特性,使用它我们可以获取当前DOM元素对象,以便执行相关操作. <div id="app"> <input ...

  10. eslint 错误提示

    “Missing semicolon.” : “缺少分号.”, “Use the function form of \”use strict\”.” : “使用标准化定义function.”, “Un ...