首页 / JAVA / Java并发编程实战 -- 基础知识
Java并发编程实战 -- 基础知识
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java并发编程实战 -- 基础知识,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4401字,纯文字阅读大概需要7分钟。
内容图文
![Java并发编程实战 -- 基础知识](/upload/InfoBanner/zyjiaocheng/621/d8a88df6c4da477ba58cd6880ec9e189.jpg)
文章目录
???????? 平台提供的各种并发功能与开发人员在程序中需要的并发语义并不匹配!在Java语言中提供一些底层机制,例如同步和条件等待,但在使用这些机制来实现应用级的协议与策略时必须始终保持一致。
第一章 简介
- 线程使复杂的异步代码变得更简单,简化复杂系统的开发,发挥多处理器系统的计算能力
- 计算机加入操作系统来实现多个程序同时执行的原因:资源利用率、公平性、便利性
- 串行编程模型的优势在于其直观性和简单性
- 线程允许在同一个进程中同时存在多个程序控制流
- 线程还提供了一种直观的分解模式来充分利用多处理器系统的硬件并行性,而在同一个程序中的多个线程也可以被同时调度到多个CPU上运行
- 线程能够将大部分的异步工作流转换成串行工作流,降低代码的复杂度
- 使用多个线程还有助于在单处理器系统上获得更高的吞吐率
- 通过使用线程,可以将复杂并且异步的工作流进一步分解为一组简单并且同步的工作流,每个工作流在一个单独的线程中运行,并且在特定的同步位置进行交互
- 额外的性能开销:共享数据使用同步机制,往往会抑制编译器优化,使内存缓冲区中的数据无效,以及增加共享内存总线的同步流量
- 框架通过在框架线程中调用应用程序代码(回调 CallBack)将并发引入到程序中
第二章 线程安全性
- 编写线程安全代码的核心:要对状态访问操作进行管理,特别是对共享的(Shared)和可变的(Mutable)状态的访问
- 共享意味着变量可以由多个线程同时访问,可变则意味着变量的值在其生命周期内可以发生变化
- Java中的主要同步机制是关键字synchronized,提供了一种独占的加锁方式,但同步这个术语还包括volatile类型的变量,显示锁(Explicit Lock)以及原子变量
- 完全由线程安全类构成的程序不一定就是线程安全的,而在线程安全类中也可以包含非线程安全的类
- 线程安全性:当多个线程访问某个类时,这个类始终都能表现出正确的行为
- 当多个线程访问某个类时,不管运行环境采用何种调度方式或者这些线程将如何交替执行,并且在主调函数代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么称这个类是线程安全的
- 在线程安全类中封装了必要的同步机制,因此客户端无须进一步采取同步措施
- 无状态对象一定是线程安全的(大多数Sevlet)
- 竞态条件:并发编程中由于不恰当的执行时序而出现正确的结果,本质:基于一种可能失效的观察结果来做出判断或者执行某个计算
- 当某个计算的正确性取决于多个线程的交替执行时序时,那么就会发生竞态条件。最常见的竞态条件类型就是:先检查后执行(Check -Then-Act)操作,即通过一个可能失效的观测结果来决定下一步的动作
- 竞态条件 && 数据竞争
- 延迟初始化存在竞态条件,可能会导致两次调用getInstance返回不同的对象,参考懒汉式 - 单例
- 与大多数并发错误一样,竞态条件并不总是会产生错误,还需要某种不恰当的执行时序
- 复合操作:包含了一组必须以原子方式执行的操作以确保线程安全性
- 当在无状态的类中添加一个状态时,如果该状态完全由线程安全的对象来管理,那么这个类仍然是线程安全的
- 在实际情况当中,应尽可能地使用现有的线程安全对象(例如AcomicLong)来管理类的状态
- 当在不变性条件中涉及多个变量时,各个变量之间并不是彼此独立的,而是某个变量的值会对其他变量的值产生约束。因此,当更新某一个变量时,需要在同一个原子操作中对其他变量同时进行更新
- 要保持状态的一致性,就需要在单个原子操作中更新所有相关的状态变量
- 每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁,Java内置锁相当于一种互斥体(互斥锁)
- 内置锁是可重入的,重入意味着获取锁的操作的粒度是线程,而不是调用
- 重入进一步提高了加锁行为的封装性,简化OOP并发代码的开发;避免了子类继承父类同步方法死锁问题的发生
- 如果在复合操作的执行过程中持有一个锁,那么会使复合操作成为原子操作
- 如果用同步来协调对某个变量的访问,那么在访问这个变量的所有位置上都要使用同步
- 对于可能被多个线程同时访问的可变状态变量,在访问它时都需要持有同一个锁,在这种情况下,我们称状态变量是由这个锁保护的
- 对象的内置锁与其状态之间没有内在的关联;当获取与对象关联的锁时,并不能阻止其他线程访问该对象,某个线程在获得对象的锁之后,只能阻止其他线程获得同一个锁
- 每个共享的和可变的变量都应该只由一个锁来保护,从而使维护人员知道是哪一个锁
- 对于每个包含多个变量的不变性条件,其中涉及的所有变量都需要由同一个锁来保护
- 虽然
synchronized
方法可以确保单个操作的原子性,但如果要把多个操作合并为一个复合操作,还是需要额外的加锁机制 - 通常,在简单性与性能之间存在着相互制约因素。当实现某个同步策略时,一定不要盲目地为了性能而牺牲简单性(这可能会破坏安全性)
- 当执行时间较长的计算或者可能无法快速完成的操作时(例如,网络I/O或控制台I/O,)一定不要持有锁
第三章 对象的共享
- 同步的另一个重要的方面:内存可见性(Memory Visibility)
- 只要有数据在多个线程之间共享,就使用正确的同步
- 在没有同步的情况下,编译器、处理器以及运行时等都可能对操作的执行顺序进行一些意向不到的调整。在缺乏足够同步的多线程程序中,要想对内存操作的执行顺序进行判断,几乎无法得出正确的结论
- 举
标签:,,,,,,,, 来源: https://blog.csdn.net/weixin_44556968/article/details/109964624
内容总结
以上是互联网集市为您收集整理的Java并发编程实战 -- 基础知识全部内容,希望文章能够帮你解决Java并发编程实战 -- 基础知识所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。