【问题标题】:Synchronized Implementation of a Business Logic业务逻辑的同步实现
【发布时间】:2011-02-05 07:36:04
【问题描述】:

使用现有的同步 Java 类(Hashtable、StringBuffer、Vector)实现

在我们实现非同步 Java 类(HashMap、StringBuilder、ArrayList)时同步块

从 Collections.synchronizedXXX() 方法创建一个同步的集合对象,然后使用它(当然,我不能像这样同步 StringBuilder。!!)

在多线程场景中,以上哪种方式是在不影响性能的情况下实现同步的最佳方式?

提前致谢!!!!

【问题讨论】:

  • StringBuilder 未同步,StringBuffer 已同步。
  • 感谢您的关注.. +1 为您服务..!

标签: java multithreading synchronization


【解决方案1】:

最佳方法取决于您的代码到底要做什么以及您需要的原子性级别。有时Collections.synchronizedWhatever 很好;有时您需要自己进行同步。

就性能而言,您只需确保将输入的synchronized 块的数量降至最低。差别不大

(example A)
List l = Collections.synchronizedList(originalList);
l.add(something);

(example B)
synchronized (originalList) {
    originalList.add(something);
}

因为它们都进入了一个同步块。然而:

(example C)
List l = Collections.synchronizedList(originalList);
l.add(something);
int index = l.indexOf(something);

将进入两个同步块,而

(example D)
synchronized (originalList) {
    originalList.add(something);
    int index = originalList.indexOf(something);
}

只会输入一个同步块。当然,它在该块中花费的时间更长,因此可能会增加争用,但是 add 和 indexOf 现在的行为就像一个单一的原子操作。这可能是也可能不是您想要的:它完全取决于应用程序。

编辑:回答 Deepak 的问题:

示例 C 中的 'synchronizedList' 意味着对 'l' 上的方法的每次调用都将包装在同步块中。你可以认为 C 是这样做的:

synchronized (originalList) {
    originalList.add(something);
}
synchronized (originalList) {
    int index = originalList.indexOf(something);
}

这里有一些额外的成本,但除非它位于代码的性能关键部分,否则它可能不会成为问题。我建议您在考虑优化代码之前多考虑确保代码行为正确。很难获得正确的线程安全代码,所以要非常小心你如何编写东西。例如,在 C 中,“l.add(something)”和“l.indexOf(something)”之间可能存在竞争条件。 D 没有相同的竞争条件,因为这两个操作都在一个同步块内。

Brian Goetz 的书(Java Concurrency in Practice)是学习如何编写线程安全代码的绝佳资源。我强烈推荐它。我确定它在亚马逊上。

【讨论】:

  • 感谢您的回复!具有许多操作的单个同步锁会花费更多时间,还是对内部同步对象的许多操作会花费更多时间?
  • 您能否简要解释一下在您上面引用的示例代码中如何有 2 个同步块以及如何有一个同步块。请回复。您能否向我们提供一个演示上述性能的代码2例
  • @Radkrish:进入或离开同步块相当昂贵,因此最好将它们最小化。在一个同步块中执行 10 次操作将比执行相同的 10 次操作更快,如果它们每个都进入和离开一个块。
  • @Deepak:更新了答案。虽然进入/离开同步块确实相对昂贵,但除非你真的需要,否则你不应该费心优化。优化也非常困难,因为很容易引入竞争条件并产生令人讨厌的争用问题。
  • 感谢@Cameron 很好的例子
猜你喜欢
  • 2021-02-17
  • 1970-01-01
  • 2012-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
相关资源
最近更新 更多