浅谈Java并发编程系列(一)—— 如何保证线程安全

线程安全类

保证类线程安全的措施:

  1. 不共享线程间的变量;数据库

  2. 设置属性变量为不可变变量;编程

  3. 每一个共享的可变变量都使用一个肯定的锁保护;安全

保证线程安全的思路:

1. 经过架构设计

经过上层的架构设计和业务分析来避免并发场景。好比须要用多线程或分布式集群统计一堆用户的相关统计值,因为用户的统计值是共享数据,所以须要保证线程安全。从业务上分析出用户之间的数据并不共享,所以能够设计一个规则来保证一个用户的计算工做和数据访问只被一个线程或一台机器完成,这样从设计上避免了接下来可能的并发问题。多线程

2. 保证类无状态

有状态会限制横向扩展能力,也可能产生并发问题。若是类是无状态的,那它永远是线程安全的。所以在设计阶段尽量用无状态的类来知足业务需求。架构

3. 区别原子操做和复合操做

常见的复合操做包括check-then-act, i++等。虽然check-then-act从表面上看很简单,但却广泛存在与咱们平常的开发中,特别是在数据库存取这一块。好比咱们须要在数据库里存一个客户的统计值,当统计值不存在时初始化,当存在时就去更新。若是不把这组逻辑设计为原子性的就颇有可能产生出两条这个客户的统计值。
在单机环境下处理这个问题还算容易,经过锁或者同步来把这组复合操做变为原子操做,但在分布式环境下就不适用了。通常状况下是经过在数据库端作文章,好比经过惟一性索引或者悲观锁来保障其数据一致性。固然任何方案都是有代价的,这就须要具体状况下来权衡。并发

4. 锁

使用锁应注意:分布式

  • 每一个共享变量必须由一个肯定的锁保护。性能

  • 使用锁会有性能损失.net

  • 锁不能解决在分布式环境共享变量的并发问题。线程

参考:探索并发编程(二)------写线程安全的Java代码

相关文章
相关标签/搜索