【Java并发基础】并发编程领域的三个问题:分工、同步和互斥
前言
可以将Java并发编程抽象为三个核心问题:分工、同步和互斥。
这三个问题的产生源自对性能的需求。最初时,为提高计算机的效率,当IO在等待时不让CPU空闲,于是就出现了分时操作系统也就出现了并发。后来,多核CPU出现,不同的任务可以同时独立运行,于是就出现了并行【分工】。有了分工后,效率得到了很大的提升,但是为了更合理的安排以及控制任务的进行,就需要让进程之间可以通信【同步】,让彼此知道进度的执行。分工进行提高了效率,但是却带来了多线程访问共享资源会冲突的问题。于是对共享资源的访问又需要串行化。所以,依据现实世界的做法设计了锁等机制来使得多线程【互斥】访问共享资源。
分工(性能)
分工的主要工作是:如何高效拆解任务并分配给线程。
Java SDK并发包中的Executor
、Fork/Join
、Future
本质上都是分工方法。
并发编程中的一些设计模型也是指导如何分工:生产者——消费者
、Thread-Per-Message
、Work Thread
等。
同步(性能)
在并发编程的同步,主要指的就是线程间的协作。即当一个线程执行完了,该如何通知后续任务的线程展开工作。
协作一般和分工相关。Java SDK中Executor
、Fork/Join
、Future
本质上是分工方法但是也解决线程之间的协作问题(如Future异步调用,get())。Java SDK里提供的CountDownLatch
、CyclicBarrier
、Phaser
、Exchanger
也是用于解决线程之间的协作问题。
线程协作问题都可以被描述为:当某个条件不满足时,线程需要等待,当某个条件满足使,线程需要被唤醒执行。
互斥(正确性/线程安全)
互斥指的是:在同一时刻,只允许一个线程访问共享变量。
因为 可见性、有序性和原子性(后面会有文章介绍)问题,多个线程访问同一个共享变量会导致结果的不确定 。
为了解决这三个问题,Java语言引入了内存模型,内存模型提供了一系列的规则,利用这些规则我们可以避免可见性问题、有序性问题,但是还不能完全解决线程安全问题。
解决线程安全问题的核心方案还是互斥。
实现互斥的核心技术就是锁。 Java语言中synchronized
、SDK中的各种Lock都可以解决互斥问题,但是锁却会带来性能问题,于是我们就需要平衡。
主要方案有:分场景优化,优化读多写少场景:ReadWriteLock
、StampledLock
以及无锁结构Java SDK中的原子类;其他方案,原理为不共享变量或者变量只允许读,Java中提供了Thread Local
和Final
关键字和Copy-on-write
模式。
小结
在看极客时间专栏《Java并发编程实战》学习攻略时,感触还是比较深。平时学习知识都是“独立”的,没有一种“全局”观念,也很少联系其他一些理论来侧面验证学习的知识,导致学过后就很容易忘记。看了这篇专栏前言后,总结出:学习知识时,要跳出来看全景,钻进去看本质。要知道每一种技术背后都应该有理论支持,并且这个理论可能是跨领域的,所以,掌握技术背后的理论十分很重要!
针对Java并发编程应该要结合操作系统一起来学习,如后面将要介绍的可见性、有序性和原子性。理解可见性就需要了解CPU和缓存的知识;理解原子性就需要理解操作系统的知识;很多无锁算法也是和CPU缓存有关。要联系起CPU、内存、I/O之间的关系。
参考:
[1]极客时间专栏王宝令《Java并发编程实战》
【Java并发基础】并发编程领域的三个问题:分工、同步和互斥的更多相关文章
- 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥) 介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...
- Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可以看作是Unix进程的表亲,同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间, ...
- Java之基础(1) - 编程中“为了性能”尽量要做到的一些地方
最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Ja ...
- java 25 - 2 网络编程之 网络通信三要素
网络通信三要素 IP地址: InetAddress 网络中设备的标识,不易记忆,可用主机名(计算机的标识号) 端口号: 用于标识进程的逻辑地址,不同进程的标识(正在运行的软件的标识号) 传输协议: 通 ...
- java并发编程笔记(三)——线程安全性
java并发编程笔记(三)--线程安全性 线程安全性: 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现 ...
- 【Java并发基础】利用面向对象的思想写好并发程序
前言 下面简单总结学习Java并发的笔记,关于如何利用面向对象思想写好并发程序的建议.面向对象的思想和并发编程属于两个领域,但是在Java中这两个领域却可以融合到一起.在Java语言中,面向对象编程的 ...
- 艾编程coding老师课堂笔记:java设计模式与并发编程笔记
设计模式概念 1.1 什么是设计模式 设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路.它不是语法规定,而是一套用来提高代码可复用性.可维护性.可读性. ...
- Java 并发基础
Java 并发基础 标签 : Java基础 线程简述 线程是进程的执行部分,用来完成一定的任务; 线程拥有自己的堆栈,程序计数器和自己的局部变量,但不拥有系统资源, 他与其他线程共享父进程的共享资源及 ...
- Java并发基础:进程和线程之由来
转载自:http://www.cnblogs.com/dolphin0520/p/3910667.html 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程. ...
随机推荐
- JS的作用域链与this指向
JS的作用域链是在函数创建时创建的.而this对象是在函数运行期间绑定的. 下面看几个例子,说明JS的作用域链和this是两套分离的链. 1) var name = 'window下的name< ...
- Python--day43--补充之主键和外键
主键只有一个,但是可以用两列不为空的值组成:
- 试用ZooKeeper
ZooKeeper下载 通过ZooKeeper官网下载最新的稳定版本 解压ZooKeeper到某个目录,其目录结构为: 运行环境要求 系统环境 ZooKeeper对于市面上各种操作系统都有了不错的支持 ...
- apache WEB服务器安装(包括虚拟主机)
一.apache下载编译安装 yum install apr apr-devel apr-util apr-util-devel gcc-c++ wget tar -y cd /usr/src wge ...
- Android studio 使用git仓库记录
studio 绑定git settings --> verson control -->git 在项目文件目录右击打开git bash here操作界面 查看git项目安装位置 找到id_ ...
- K:缓存数据库双写数据一致性方案
对于缓存和数据库双写,其存在着数据一致性的问题.对于数据一致性要求较高的业务场景,我们通常会选择使用分布式事务(2pc.paxos等)来保证缓存与数据库之间的数据强一致性,但分布式事务的复杂性与对资源 ...
- python基础[16]——解决django连接mysql数据库报错的问题
Models.py #创建数据表 from django.db import models from django.utils import timezone from tinymce.models ...
- jenkins安装自动部署
1.1简介: 开源项目,一个可扩展的持续集成引擎.提供了一种易于使用的持续集成系统,能实施监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表的形式形象地展示项目构建的趋势和稳定性.还做到持 ...
- 洛谷$P4249\ [WC2007]$剪刀石头布 网络流
正解:网络流 解题报告: 传送门$QwQ$ 题目大意其实就说有一个$n$个节点的有向完全图,然后部分边的方向已经给定了,要求确定所有边的方向使三元环数目有$max$.这里三元环的定义是说三条边的方向一 ...
- $HDU1846\ Brave\ Game$ 博弈论
正解:博弈论 解题报告: 传送门! 巴什博奕板子题鸭$QwQ$ 就有个结论,是说当$(m+1)\mid n$时先手必败,否则必胜 这个瞎证明一下就能出来 就考虑当$(m+1)\mid 1$时,若先手取 ...