IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java 并发 深入 1-基础知识 -> 正文阅读

[Java知识库]Java 并发 深入 1-基础知识

0. So tell me how you feel ~

1. 修复一个可变状态量没有被合适的同步的简单思路

不在线程间共享这个状态

将状态修改为不可变量

在所有可能访问状态的地方使用同步

2. 代码封装性 & 线程安全性

(这里调整了一下书中关于二者的取舍话题的顺序)

访问某个变量的代码越少,就越容易确保对变量的所有访问都实现正确的同步,同时也更容易找出变量在哪些条件下被访问。

Java语言并没有强制要求将状态都封装在类中,开发人员完全可以将状态保存在某个公开的域(甚至公开的静态域)中,或者提供一个对内部对象的公共引用。

面向对象的技术不仅有助于编写结构优雅、可维护性高的类,还有助于编写出线程安全的类。

在某种情况中,良好的面向对象设计技术与实际情况的需求并不一致。在这种情况中,可能需要牺牲一些良好的设计原则,以换取性能或者对遗留代码的向后兼容。

在任何情况中,只有当类中仅包含自己的状态时,线程安全类才是有意义的。

3. 线程安全性的定义

我们将单线程的正确性近似定义为"we know it when we see it"(正因并发下可能出现的情况更加复杂,作者将线程安全性起了个外号"代码的可信性")。

当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类时线程安全的。

4. 竞态条件 & 原子性 & 复合操作

java的自增操作,是一个"读取-修改-写入"的操作序列,并不是原子的。

当计算的正确性取决于多个线程的交替执行时序时,那么就会发生竞态条件。

最常见的竞态条件类型就是"先检查后执行",可以参考书中的经典样例"我去看看他是否在另一家星巴克"以及延迟初始化(将对象的初始化操作推迟到实际被使用时才执行,同时要确保只被初始化一次。)

并非所有竞态条件都是数据竞争(并发访问非共享的非final域,如果该域没有采用同步来协同,将导致读、写线程无法正确的访问该域),反之亦然,二者都可能导致并发程序失败。

假定有两个操作A和B,如果执行A的线程来看,当另一个线程执行B时,要么将B全部执行完,要么完全不执行B,那么A和B对彼此来说是原子的。

加锁机制是java中确保原子性的内置机制,可以修复复合操作中的线程安全性。

5. 加锁机制

有时候,尽管原子引用本身是线程安全的,但是当不变性条件中涉及多个变量,各个变量之间并不是彼此独立的,而是某个变量的值会对其他变量的值产生约束,当更新一个变量时,需要在同一个原子操作中对其他变量同时进行更新,否则仍然存在竞态条件。

静态的synchronized方法以Class对象作为锁。

因为java对象的内置锁(或称做“监视器锁”)是一种互斥锁,那么当某个线程试图获取一个已经持有的锁的时候,该线程将阻塞自己,故java的内置锁是可重入的。

“重入”意味着获取锁的操作的粒度是“线程”,并不是“调用”。重入的一种实现方法是,为每个锁关联一个获取计数值和一个所有者线程。

5. 用锁来保护状态

一种错误的认知:只有写入共享变量时,才需要使用同步。事实上,所有访问到状态的位置都需要使用同步。

当获取与对象关联的锁时,并不能阻止其他线程访问该对象,某个线程在获得对象的锁之后,只能阻止其他线程获得同一个锁。

6. 活跃性&性能

(这里针对第一章提及的问题,跟进一步的讨论,还是很喜欢这种渐进式的讨论…)

当我们将内置锁置于servlet的入口方法签名的时候,可以过于极端的保证线程安全,但是这将导致服务的响应性过低,无法令人接受。

于是,我们理所当然的通过缩小同步代码块的作用范围,可以做到既确保servlet的并发性,同时兼顾线程安全性。缩小同步代码块作用范围的前提是,避免将本应是原子的操作拆分到不同的同步代码块中。

为了进一步提升服务的并发性,我们可以将不影响共享状态并且执行时间较长的操作从同步代码块中剥离出来(比如网络IO、控制台IO、比较耗时的运算),从而使得每个同步代码块中的代码路径都比较短。

书中还提到了:一定不要为了盲目地提高性能而牺牲了简单性(这可能会破坏安全性)。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 13:44:53  更:2022-01-01 13:45:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:02:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码