当我学习Java时,使用了基础,Pascal,COBOL和C的大约20年的过程编程背景。当时,我认为关于Java的最困难的事情是将我的头放在OOP术语和概念上。如今,我拥有将近8年的Java坚实开发经验,我得出的结论是,用Java和类似C#这样的类似语言进行编程的最困难的事情就是多线程/并行方面。
编码可靠且可扩展的多线程应用程序非常困难!随着处理器的发展趋势是“更广泛”而不是更快地增长,它正迅速变得至关重要。
当然,最困难的领域是控制线程之间的交互以及由此产生的错误:死锁,竞争条件,陈旧的数据和延迟。
因此,我对您的问题是:您采用哪种方法或方法来生成安全的并发代码,同时减少出现死锁,延迟和其他问题的可能性?我想出了一种与众不同的方法,但是在一些大型应用程序中效果很好,我将在此问题的详细解答中分享它。
最佳答案
刚才有很多技术正在进入公众意识(例如:最近几年)。一个很大的是 Actor 。这是Erlang最初带到网格中的东西,但后来被诸如Scala(JVM上的actor)之类的较新语言所继承。尽管参与者确实可以解决所有问题,但确实可以使推理代码和确定故障点变得更加容易。由于它们迫使您使用通过共享可变状态传递的连续性,因此它们也使设计并行算法变得更加简单。
您应该关注Fork/Join,尤其是在使用JVM的情况下。道格·李(Doug Lea)撰写了有关该主题的开创性论文,但是多年来,许多研究人员对此进行了讨论。据我了解,Doug Lea的引用框架计划包含在Java 7中。
在侵入性较小的级别上,简化多线程应用程序通常所需的唯一步骤仅仅是降低锁定的复杂性。细粒度的锁定(Java 5风格)对于吞吐量非常有用,但是很难正确实现。通过Clojure获得一定关注的另一种锁定方法是软件事务存储(STM)。这与常规锁定基本上是相反的,因为它是乐观的而不是悲观的。首先,假设您不会发生任何冲突,然后让框架在问题发生时和问题解决时予以解决。数据库通常以这种方式工作。这对于低冲突率的系统上的吞吐量非常有用,但是最大的胜利在于算法的逻辑组件化。无需将某个锁(或一系列锁)与某些数据任意关联,您只需将危险代码包装在事务中,然后让框架找出其余的代码即可。您甚至可以从像GHC的STM monad或我的实验性Scala STM之类的STM实现中获得相当多的编译时检查。
有许多用于构建并发应用程序的新选项,您选择哪种取决于很大程度上取决于您的专业知识,语言和要建模的问题类型。通常,我认为参与者与持久的,不变的数据结构相结合是一个可靠的选择,但是正如我所说的那样,STM的侵入性较小,有时可以带来更直接的改进。
关于multithreading - 最佳编程方法/方法以确保线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/256517/