《Java并发编程实战》---线程安全性

多个线程对共享和可变数据的操作,操作的结果可能会依赖于线程对数据的访问顺序,这就是线程安全问题;

线程安全性是一个代码上使用的术语,但它只是与状态相关的,因此只能应用于封装其状态的整个代码,这可能是一个对象,也可能是整个程序;

1:线程安全类

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

编写线程安全的代码,核心在于:对状态访问操作进行管理,特别是对“共享”的和“可变”的状态的访问;

对象的状态是指,存储在状态变量(例如实例或者静态域)中得数据,对象的状态可能还包括其他依赖对象的域(HashMap的状态不仅存储在对象本身,还存储在需要Map.Entry对象中)

2:实现安全性的三种方式

1:不在线程之间共享状态变量

2:讲状态变量修改为不可变变量

3:在访问状态变量时使用同步

下面的文章会分别介绍如何通过这些方式去实现线程安全性以及java提供的具体类

3:线程安全性的分类方法

google了一下线程安全性相关内容,发现一个对线程安全性进行分类的标准,当前还没有一个比较标准的分类方法;
Bloch 给出了描述五类线程安全性的分类方法:不可变、线程安全、有条件线程安全、线程兼容和线程对立;
1:不可变 
     不可变的对象一定是线程安全的,并且永远也不需要额外的同步。因为一个不可变的对象只要构建正确,其外部可见状态永远也不会改变,永远也不会看到它处于不一致的状态。Java  类库中大多数基本数值类如 Integer、String和 BigInteger都是不可变的。 
2:线程安全 
     由类的规格说明所规定的约束在对象被多个线程访问时仍然有效,不管运行时环境如何排列,线程都不需要任何额外的同步。这种线程安全性保证是很严格的——许多类,如Hashtable或者Vector都不能满足这种严格的定义。
3:有条件的线程安全 
     有条件的线程安全类对于单独的操作可以是线程安全的,但是某些操作序列可能需要外部同步。最常见的例子是遍历由Hashtable或者Vector或者返回的迭代器——由这些类返回的fail-fast迭代器假定在迭代器进行遍历的时候底层集合不会有变化。为了保证其他线程不会在遍历的时候改变集合,进行迭代的线程应该确保它是独占性地访问集合以实现遍历的完整性。通常,独占性的访问是由对锁的同步保证的——并且类的文档应该说明是哪个锁(通常是对象的内部监视器(intrinsic monitor))
4:线程兼容 
     线程兼容类不是线程安全的,但是可以通过正确使用同步而在并发环境中安全地使用。这可能意味着用一个synchronized块包围每一个方法调用,或者创建一个包装器对象,其中每一个方法都是同步的(就像Collections.synchronizedList()一样)。也可能意味着用synchronized块包围某些操作序列。 常见类:ArrayList、HashMap、SimpleDateFormat、Connection和ResultSet等。
5:线程对立 
     线程对立类是那些不管是否调用了外部同步都不能在并发使用时安全地呈现的类。线程对立很少见,当类修改静态数据,而静态数据会影响在其他线程中执行的其他类的行为,这时通常会出现线程对立。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值