您的位置:首页 > 编程语言 > Java开发

JAVA并发编程实战---第二章:线程安全性

2016-05-05 16:51 351 查看
  对象的状态是指存储在状态变量中的数据。对象的状态可能包括其他依赖对象的域。例如HashMap的状态不仅存储在HashMap本身,还存储在许多Map.Entry对象中。对象的状态中包含了任何可能影响其外部可见性为的数据。

  共享意味着变量可以由多个线程同时访问,可变意味着变量的值在其生命周期内可能发生变化。

  线程安全性:当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么这个类就是线程安全的。

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

  无状态对象一定是线程安全的。

  无状态对象:不包含任何域,也不包含对其他类中域的引用。

  当在无状态的类中添加一个状态时,如果该状态完全由线程安全的对象来管理,那么这个类仍然是线程安全的。

竞态条件

  竞态条件:从多线程通信角度来讲,是指两个或多个线程对共享数据的操作时,最终的结果取决于这些线程的执行顺序。

最常见的竞态条件类型就是:先检查后执行(Check-Then-Act)。其本质就是-----基于一种可能失效的观察结果来做出判断或执行某个计算。

读取-修改-写入。基于对象之前的状态来定义对象状态的转换。

  竞态条件并不是总是会产生,还需要某种不恰当的执行顺序。

要避免竞态条件问题,就必须在某个线程修改该变量时,通过某种方式防止其他线程使用这个变量,从而保证其他线程只能在修改操作完成之前或之后读取和修改状态,而不是修改过程中。

  当在不变形条件中涉及多个变量时,各种变量之间并不是彼此独立的,而是某个变量的值会对其他变量的值产生约束。因此,当更新一个变量时,需要在同一个原子操作中对其他变量同时进行更新。要保持状态的一致性,就需要在单个原子操作中更新所有相关的状态变量。

  对于每个包含多个变量的不变性条件,其中涉及的所有变量都需要同一个锁来保护。

内置锁

  每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁。线程在进入同步代码块之前自动获取锁,并且在退出同步代码块时自动释放锁。

  Java的内置锁是互斥锁。

  内置锁是可重入的,因此如果某个线程视图获取一个已经由它自己持有的锁,那么这个请求就会成功。重入意味着获取锁操作的粒度是线程而不是调用。

  由于锁能够使其保护的代码路径以串行的方式来访问,因此可以通过锁来构造一些协议以实现对共享状态的独占访问。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: