处理线程安全程序

问题描述:

全部,处理线程安全程序

写什么应该是写一个线程安全程序的方法。给定一个问题的陈述,我的观点是:

1>开始用编写代码的单线程环境。
2>下划线这将需要的原子,并与可能并发类
3替换字段>下划线临界区和将它们括在同步
4>执行测试死锁

没有人有其他任何建议接近或改进我的方法。到目前为止,我可以看到自己将大部分代码放在同步块中,我相信这是不正确的。

编程在Java中

编写正确的多线程代码是很难的,并没有一个神奇的公式或设定的步骤,这将让你有。但是,您可以遵循一些准则。

个人而言,我不会与单线程环境中编写代码开始,然后将其转换为多线程的。良好的多线程代码是从一开始就考虑到多线程的。字段的原子性只是并发代码的一个元素。

你应该在什么区域的代码需要是决定多线程(在多线程应用程序,通常不是一切都需要是线程安全的)。然后你需要设计这些部分将如何线程安全。使代码线程安全的一个区域的方法可能不同于使其他区域不同。例如,了解是否有大量的阅读与写作很重要,可能会影响您用来保护数据的锁的类型。

不变性也线程代码的一个关键要素。当元素是不可变的(即不能被改变)时,你不需要担心多个线程修改它们,因为它们不能被改变。这可以极大地简化线程安全问题,并让您专注于您将拥有多个数据读取器和编写器的位置。

在Java并发的了解细节(和Java内存模型的详细信息)是非常重要的。如果您还不熟悉这些概念,我建议你阅读Java并发在实践http://www.javaconcurrencyinpractice.com/

+0

+1不变性。最小化可写状态可以缓解许多并发问题。 – ide 2010-10-11 01:52:07

任何变量(内存)可能同时被多个线程访问,需要通过一个同步机制来保护。

您应该使用最终不变领域只要有可能,你想改变任何其他数据里面添加:

synchronized (this) { 
    // update 
    } 

记住,有时东西刹车,如果出现这种情况,你不不想通过采取一切可能的方式来延长程序执行时间 - 而是“快速失败”。

正如你所问“线程安全”,而不是并发性能,那么你的做法实质上是声音。但是,使用同步的线程安全的程序在结构/程序的任何级别竞争中可能不会在多CPU环境中扩展。

就我个人而言,我喜欢尝试并确定*别的状态更改,并尝试考虑如何使它们成为原子,并让状态更改从一个不可变状态转移到另一个状态 - 如果您喜欢,请在写入时复制。然后,实际写入可以是对原子变量或同步更新的比较和设置操作,也可以是任何策略工作/执行得最好(只要它安全地发布新状态)。

如果您的新状态非常不同(例如需要更新多个字段),这可能会有点困难,但我已经看到它非常成功地解决了同步访问的并发性能问题。

购买并阅读Brian Goetz的“实践中的Java并发性”。