线程安全

 

线程安全:当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的。(Java并发编程实战)

如果当多个线程访问同一个可变的状态变量时,程序出现错误。可以通过以下方式可以修复该问题。
1.不在线程之间共享该状态变量。
2.将状态变量修改为不可变的变量。
3.在访问状态变量时使用同步。

 

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

对象不可变的条件:
1.对象创建以后其状态就不能修改。
2.对象的所有域都是final类型。
3.对象是正确创建的。

竞态条件:当某个计算的正确性取决于多个线程的交替执行时序时,就会发生竞态条件。
竞态条件的本质:基于一种可能失效的观察结果来做出判断或者执行某个计算。

数据竞争:如果在访问共享的非final类型的域时没有采用同步来进行协同,那么就会出现数据竞争。


Java的内置锁(synchronized),也叫监视器锁,相当于一种互斥体,或互斥锁
内置锁是可重入的(代表获取锁的操作粒度是线程,而不是调用。),即如果某个线程尝试获得一个已经由它自己持有的锁,那么这个请求就会成功。
其中一种实现方法是,为每个锁关联一个获取计数值和一个所有者线程。


Happens-Before规则:
1.程序顺序规则:如果程序中A操作在B操作之前,那么在线程中A操作将在B操作之前执行。
2.监视器锁规则:在监视器锁上的解锁操作必须在同一个监视器锁上的加锁操作之前执行。
3.Volatile变量规则:对Volatile变量的写入操作必须在对该变量的读操作之前执行。
4.线程启动规则:在线程上对Thread.start的调用必须在该线程中执行任何操作之前执行。
5.线程结束规则:线程中的任何操作都必须在其他线程检测到该线程已经结束之前执行,或者从Thread.join中成功返回,或者在调用Thread.isAlive时返回false。
6.中断规则:当一个线程在另一个线程上调用interrupt时,必须在被中断线程检测到interrupt调用之前执行。
7.终结器规则:对象的构造函数必须在启动该对象的终结器之前执行完成。
8.传递性:如果操作A在操作B之前执行,并且操作B在操作C之前执行,那么操作A必须在操作C之前执行。

 

Volatile变量使用条件:
1.对变量的写入操作不依赖变量的当前值,或者能确保只有单个线程更新变量的值。
2.该变量不会与其他状态变量一起纳入不可变性条件中。
3.在访问变量时不需要加锁。

 

posted @ 2017-11-05 08:23  emoji的博客  阅读(169)  评论(0编辑  收藏  举报