编写可靠且可扩展的多线程应用程序确实很难!随着处理器趋于“更宽”而不是更快的趋势,这变得非常关键。
当然,最困难的领域是控制线程之间的交互以及由此产生的错误:死锁、竞争条件、过期数据和延迟等。
因此,我的问题是:您采用什么方法或方法论来生成安全的并发代码,同时减轻死锁、延迟和其他问题的潜在风险?我想到了一种有点非传统但在几个大型应用程序中表现良好的方法,我将在对这个问题的详细回答中分享。
在Java中,关于线程安全性并没有一个真正的标准答案。然而,至少有一本非常好的书: Java Concurrency in Practice。我经常参考它(尤其是当我出差时使用在线Safari版本)。
我强烈建议您深入阅读这本书。您可能会发现,您的非传统方法的成本和收益得到了深入的研究。
http://en.wikipedia.org/wiki/Dataflow_programming
http://en.wikipedia.org/wiki/Flow-based_programming
此外,它有几个优点,如惊人的灵活配置、分层;程序员(组件程序员)不必编写业务逻辑,这是在另一个阶段完成的(将处理网络组合在一起)。看起来你的IOC有点像FBP :-) 如果JavaFBP代码能够得到像你这样精通编写线程安全代码的人的彻底审查,那将是非常棒的... 它在SourceForge的SVN上。
一些专家认为,回答你的问题的方法是完全避免使用线程,因为几乎不可能避免意外问题。引用线程问题中的话:
我们开发了一个过程,其中包括代码成熟度评级系统(有四个级别:红色、黄色、绿色和蓝色)、设计审查、代码审查、夜间构建、回归测试和自动化代码覆盖度指标。确保程序结构的一致视图的内核部分于2000年初编写,经过黄色的设计审查和绿色的代码审查。审阅人员包括并发专家,而不仅仅是没有经验的研究生(Christopher Hylands(现在是Brooks)、Bart Kienhuis、John Reekie和[Ed Lee]都是审阅人员)。我们编写了回归测试,实现了100%的代码覆盖率......该系统本身开始被广泛使用,每次使用该系统都会运行此代码。直到四年后的2004年4月26日,才出现死锁问题。
设计多线程新应用程序的最安全方法是遵守以下规则:
不要在设计之下进行设计。
这是什么意思呢?
想象一下,您已经确定了应用程序的主要构建块。让它成为GUI、一些计算引擎。通常,一旦团队规模足够大,团队中的一些人会要求“库”来在这些主要构建块之间“共享代码”。虽然在开始时定义主要构建块的线程和协作规则相对容易,但所有这些努力现在都面临着危险,因为“代码重用库”将被糟糕地设计,需要时进行设计,并且布满了感觉正确的锁和互斥量。这些临时库是您设计之下的设计,也是您线程架构的主要风险。
该怎么办呢?
最后但并非最不重要的是,考虑在你的主要构建块之间进行一些基于消息的交互;例如,参见经常提到的Actor模型。