2.1 线程安全性

当多个线程访问某个类时,不论这些线程如何交替执行,这个类始终都能表现出正确的行为,且主调代码中不需要任何额外的同步或协同,则称这个类是线程安全的。

类不变性条件(Invariant):约束对象的状态
后验条件(Postcondition):约束对象操作的结果

保证正确的行为是指:任何操作都不会违背类不变性条件或后验条件。在线程安全类的对象的实例上执行的任何串行或并行操作都不会使对象处于无效状态。

2.2 原子性

竞态条件

某个计算过程的正确性取决于多个线程交替执行时序。

注:数据竞争:多个线程同时对内存的同一块数据进行了操作,当至少有一个线程对其进行了写操作时就会发生数据竞争

竞态条件常见情况:

  1. check-then-act:延迟初始化
  2. 读取-修改-写入:递增运算

复合操作

包含了一组必须以原子方式执行的的操作以确保线程安全性。

  1. 使用原子变量类java.util.concurrent.atomic包

    并不一定正确,当不变性条件中涉及多个变量,各个变量之间相互约束,当更新其中一个变量时需要同时更新其它变量。

  2. 单个原子操作中更新所有相关的状态变量,使用同步代码块

2.3 加锁机制

内置锁

每个Java对象都可以用作一个实现同步的锁,称为内置锁(Intrinsic Lock)。线程在进入同步代码块前会自动获得锁,并且在退出同步代码块时自动释放。

同步代码块(Synchronized Block)

包含一个作为锁的对象引用,一个作为由这个锁保护的代码块。

  1. 修饰实例方法,则同步代码块的锁就是方法调用所在的对象
  2. 修改静态方法,则以Class对象作为锁。

重入

锁是可重入的,即获取锁的操作的粒度是线程,而不是调用。每个锁关联有一个计数器值和一个所有者线程,计数器值为0时,锁被认为不被持有。

用锁保护变量状态

如果用同步来协调对某一个变量的访问,则要满足:

  1. 访问该变量的所有位置都需要同步
  2. 所有同步需要使用同一个锁

加锁约定:

  1. 将所有可变状态都封装在对象内部,并通过对象的内置锁对所有访问可变状态的代码路径进行同步
  2. 对于每个包含多个变量的不变性条件,其中涉及的所有变量都需要由同一个锁来保护

通常不同时使用多种不同的同步机制:例如,同时使用原子变量和同步代码块。

JAVA并发编程实战笔记 第二章的更多相关文章

  1. 《Java并发编程实战》第二章 线程安全性 读书笔记

    一.什么是线程安全性 编写线程安全的代码 核心在于要对状态訪问操作进行管理. 共享,可变的状态的訪问 - 前者表示多个线程訪问, 后者声明周期内发生改变. 线程安全性 核心概念是正确性.某个类的行为与 ...

  2. java并发编程实战:第二章----线程安全性

    一个对象是否需要是线程安全的取决于它是否被多个线程访问. 当多个线程访问同一个可变状态量时如果没有使用正确的同步规则,就有可能出错.解决办法: 不在线程之间共享该变量 将状态变量修改为不可变的 在访问 ...

  3. 《Java并发编程实战》第二章 线程安全 札记

    一个.什么是线程安全 编写线程安全的代码 其核心是管理国事访问的操作. 共享,可变的状态的訪问 - 前者表示多个线程訪问, 后者声明周期内发生改变. 线程安全性 核心概念是正确性.某个类的行为与其规范 ...

  4. 【java并发编程实战】第二章:对象的共享

    1.重要的属性 可见性,不变性,原子性 1.1可见性 当一个线程修改某个对象状态的时候,我们希望其他线程也能看到发生后的变化. 在没有同步的情况下,编译器和处理器会对代码的执行顺序进行重排.以提高效率 ...

  5. Java并发编程实战.笔记十一(非阻塞同步机制)

    关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...

  6. Java并发编程实战---第六章:任务执行

    废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...

  7. Java并发编程实战 第16章 Java内存模型

    什么是内存模型 JMM(Java内存模型)规定了JVM必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对其他线程可见. JMM为程序中所有的操作定义了一个偏序关系,称为Happens-Be ...

  8. java并发编程实战笔记---(第二章)线程安全:正确性

    ThreadA__________     同步 ______________ 异步 ___________     异步 ThreadB__________         ____________ ...

  9. 【java并发编程实战】第一章笔记

    1.线程安全的定义 当多个线程访问某个类时,不管允许环境采用何种调度方式或者这些线程如何交替执行,这个类都能表现出正确的行为 如果一个类既不包含任何域,也不包含任何对其他类中域的引用.则它一定是无状态 ...

随机推荐

  1. python3基础: 元组tuple、 列表list、 字典dict、集合set。 迭代器、生成器

    一.元组: tuple Python 的元组与列表类似,不同之处在于元组的元素不能修改. 元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组 tup2 = (111, 22, 33, ...

  2. JS框架_(Bootstrap.js)实现简单的轮播图

    Bootstrap框架中 轮播(Carousel)插件是一种灵活的响应式的向站点添加滑块的方式 轮播图效果: <!DOCTYPE html> <html> <head&g ...

  3. [CSP-S模拟测试]:组合(欧拉路)

    题目传送门(内部题119) 输入格式 第一行,三个整数$T,M,N$. 接下来的$N$行,每行两个整数$u_i,v_i$($i$从$1$开始编号).允许$u_i=v_i$,也允许同样的简单词多次出现. ...

  4. vue router 如何使用params query传参,以及有什么区别

    写在前面: 传参是前端经常需要用的一个操作,很多场景都会需要用到上个页面的参数,本文将会详细介绍vue router 是如何进行传参的,以及一些小细节问题.有需要的朋友可以做一下参考,喜欢的可以点波赞 ...

  5. 错误“Object reference not set to an instance of an object”的解决方法

    在进行unity游戏制作的C#代码编写时,会遇到“NullReferenceException: Object reference not set to an instance of an objec ...

  6. Static class 与non static class的区别

    内部静态类不需要有指向外部类的引用.但非静态内部类需要持有对外部类的引用.非静态内部类能够访问外部类的静态和非静态成员.静态类不能访问外部类的非静态成员.他只能访问外部类的静态成员.一个非静态内部类不 ...

  7. Dubbo Configuration

    可配置参数 http://dubbo.apache.org/zh-cn/docs/user/references/xml/introduction.html 与 spring 整合的几种方式 Spri ...

  8. 4. 获取当前的文件夹的路径,以及当前文件名的路径 os.path.realpath

    使用os.path.realpath(__file__) 获得当前的文件夹的路径名, 使用os.path.split 进行路径切割 import os src, _= os.path.split(os ...

  9. leetcode 82 删除排序列表中的重复元素II

    与83类似,不过需要注意去除连续的重复片段的情况,如2 2 3 3这种情况,以及[1,1]这种情况下最终的cur为NULL,因此不能再令cur=cur->next; /** * Definiti ...

  10. Zxing二维码的集成使用

    在github网站搜索Zxing 详见:https://github.com/yipianfengye/android-zxingLibrary 在module的build.gradle中执行comp ...