Java并发编程-线程安全性

对象的共享和可变性

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

java中同步机制主要包括四种:

(1)synchronized 一种独占的加锁方式

(2)volatite类型的变量

(3)显式锁

(4)原子变量

无状态对象:一定是线程安全的。所谓无状态对象是指类或方法中不包含任何域也不包含其他累中域的引用,说简单一点就是,所有的参数,都是线程请求私有的,并且处理过程,产生的中间临时变量,也只对本次请求有影响,影响不到其他线程。

public class Nostatus{

public void add(int i){

i++;

}

}

Nostatus就是一个无状态对象,每个线程,请求add方法时,只对自己传入的变量都是私有的,影响不到其他线程。这个对象就是无状态对象。

原子性

在对无状态对象中间一个状态时,很有可能在多线程情况下丢失原子性。

public class Nostatus{

private int count;

public void add(int i){

i++;

++count;

}

}

其中count 在自增的过程,在多线程的情况下,会丢失一些更新操作。这时可以使用原子变量来解决次问题,Atomic变量。而不是采用synchronized 加锁的方式。原子变量,性能优于synchronized 加锁,因为减少了,得到锁和释放锁的过程。

竞态条件 先检查后执行操作是最常见的竞态条件。检查的结果,可能是失效的,从而做出错误的反应。

懒加载单例模式中,两个线程同时第一次调用单例对象获取实例,可能的结果就是,创建两个对象。从而违反了单一实例对象的本质。

复合操作

无论是先检查后执行,还是,读取-修改-写入等必须的原子操作,这些称为复合操作。java.util.concurrent.atomic 包中提供了原子变量类。对于无状态对象,中引用线程安全的对象,这个类还是线程安全的。能不加锁时,尽量不加锁。方便对对象的控制,同时也能提高效率。

猜你喜欢

转载自blog.csdn.net/qq_27224549/article/details/81703410