Java并发-线程安全性

读书可以直面你的灵魂,并对其发起拷问。

        以下内容为 Java 并发编程实战 中第一部分的总结,可以帮你快速了解多线程编程的基础知识,在后续学习中可以更快入门多线程编程。

本期主题:线程安全性

        抛开锁与同步,我们从抽象层面了解一下线程与线程安全。

线程安全性是什么

        线程安全性是对某个类来说的,我们一般说某个类具有线程安全性,就代表在多线程操作的环境下,该类的状态可以被正确的修改和读取。要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的(Share)和可变的(Mutable)状态的访问。

        状态,可以是对象中的成员变量,或者类变量(静态变量),一个类或对象可以有多个状态,每个状态都可以看做线程安全性的一个“威胁”。一个类或对象的状态越少,这个类或对象的线程安全性就越能得到保证,这一点可以与避免过度设计进行联想,毕竟很难做到完全不依赖状态进行多线程编程,所以要合理设计状态。

        如果从一开始就设计一个线程安全的类,那么比在以后再讲这个类修改为线程安全的类要容易许多。当然,如果一个类的对象不需要被多个线程进行访问,那它就不需要是线程安全的,避免过度设计!!!

两个重要概念:线程安全的程序-线程安全的类

        线程安全的程序是在多线程环境运行下不会出现错误的程序,线程安全的类是指具有线程安全性的类,也就是在多线程操作的环境下状态可以被正确读取的类。那么,线程安全的程序是否完全由线程安全的类构成?

        并不一定,完全线程安全的类构成的程序也有可能线程不安全,而线程安全的类可以由非线程安全的类组成。在任何情况下,只有当类中仅包含自己的状态时,线程安全类才是有意义的。

线程安全性的核心概念-正确性

        正确性是指,某个类的行为与其规范完全一致。这种完全一致是在任何环境下都生效的,比如多个线程同时调用某个类的对象方法,互换这些线程的调用顺序,最终结果不会发生改变。正确性在很大程度上接近线程安全性,你可以将正确性理解为线程安全性。

原子性

        如果你进行过数据库方向的学习,你应该会很清楚这个概念。某些操作具有原子性是指,这些操作是连续执行的。不存在其他操作插队的现象。这种原子性在单线程环境下很好保证,但在多线程环境下,对于这些操作,同一时刻可能有很多线程在同步执行,这时就会有别的线程插队操作导致当前线程的操作结果失败,这也叫做发生了竞态条件,竞态条件的概念下面会讲,这里举个例子看看原子性究竟是什么。

        A想要从自己的帐户中转1000块钱到B的帐户里。那个从A开始转帐,到转帐结束的这一个过程,称之为一个事务。在这个事务里,要做如下操作:

  • 1. 从A的帐户中减去1000块钱。如果A的帐户原来有3000块钱,现在就变成2000块钱了。
  • 2. 在B的帐户里加1000块钱。如果B的帐户如果原来有2000块钱,现在则变成3000块钱了。

        如果在A的帐户已经减去了1000块钱的时候,忽然发生了意外,比如停电什么的,导致转帐事务意外终止了,而此时B的帐户里还没有增加1000块钱。那么,我们称这个操作失败了,要进行回滚。回滚就是回到事务开始之前的状态,也就是回到A的帐户还没减1000块的状态,B的帐户的原来的状态。此时A的帐户仍然有3000块,B的帐户仍然有2000块。

        我们把这种要么一起成功(A帐户成功减少1000,同时B帐户成功增加1000),要么一起失败(A帐户回到原来状态,B帐户也回到原来状态)的操作叫原子性操作。如果你有兴趣,可以假设多线程状态下的插队操作情况,这种情况导致A账户金额在每次交易时都不一致,混乱甚至不合法。

竞态条件

        当某个计算的正确性却决于多个线程的交替执行顺序时,就会发生竞态条件,换句话说,程序的运行结果要看运气如何。常见的竞态条件类型就是“检查-执行”操作,即通过一个可能失效的观测结果来决定下一步的动作。

        想要避免竞态条件,就必须在某个线程修改该变量时,通过某种方式阻止其他线程使用这个变量,保证状态的一致性,我们常见的方法就是锁与同步机制。

总结

        线程安全性在脱离锁与同步机制后很难保证,从抽象的层面来讲,掌握上述概念对于后面更多多线程编程的知识学习很有必要,因为多线程编程本质上是一种访问安全思想的体现。接下来的文章会涉及到Java编程语言中具体的某种锁或者同步机制,有了抽象层面的基础,学习具象知识也就变得不难了。

  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值