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. jQuery_复制操作

    复制操作代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...

  2. Linux命令-文件管理(二)

    Linux命令-文件管理(二) Linux gitview命令 Linux gitview命令用于观看文件的内容,它会同时显示十六进制和ASCII格式的字码. 语法:gitview [-bchilv] ...

  3. sleep() 、join()、yield()有什么区别

    1sleep()方法 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行).此操作受到系统计时器和调度程序精准和准确性的影响,让其他线程有机会继续执行,但是它不释放对象锁.也就是如果有synchron ...

  4. 机器学习模型解释工具-Lime

    本篇文章转载于LIME:一种解释机器学习模型的方法 该文章介绍了一种模型对单个样本解释分类结果的方法,区别于对整体测试样本的评价指标准确率.召回率等,Lime为具体某个样本的分类结果做出解释,直观地表 ...

  5. 在MVC项目中使用Ninject

    项目结构图: App_start文件夹中的文件是VS自己创建的,其中NinjectWebCommon类在创建之初并不存在.后面会再次提到! 添加一个Home控制器.代码如下: using Essent ...

  6. hdjs---1、hdjs爬坑杂记

    hdjs---1.hdjs爬坑杂记 一.总结 一句话总结: 对hdjs这种文档和完善都不是很好的插件,应该先在项目的空页面试,成功后再用到用了框架的项目中 1.hdjs4.0.18引入select2? ...

  7. C# NAudio 变声

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. Python中转换角度为弧度的radians()方法

    Python中转换角度为弧度的radians()方法 这篇文章主要介绍了Python中转换角度为弧度的radians()方法,是Python入门中的基础知识,需要的朋友可以参考下 radians()方 ...

  9. 安装SQL Server 2008反复提示需要安装MICROSOFT NET FRAMEWORK 3 5 SP1的一个

    在安装过.net  framework 4的系统中,安装sql server 2008的安装前提之一MICROSOFT .NET FRAMEWORK 3.5 SP1时,可能已经安装并重启了,还是提示安 ...

  10. javase程序设计上机作业2

    package javaxgp.teacher.test; import java.util.Scanner; public class Demo3 { public static void main ...