2011-02-05 125 views
2

使用现有的同步Java类(Hashtable中,StringBuffer的,矢量)同步的业务逻辑

当我们执行非同步Java类同步块实施的执行情况(HashMap的,StringBuilder的,ArrayList中)

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

在多线程场景中,以上哪一种将是实现同步的最佳方法没有任何表现杀人?

在此先感谢。

+1

StringBuilder未同步,StringBuffer已同步。 – pingw33n 2011-02-05 07:55:47

+0

感谢您使它注意到.. +1为你..! – 2011-02-05 08:22:56

回答

2

最好的方法取决于你的代码试图做什么以及你需要的原子级别。有时Collections.synchronizedWhatever是好的;有时你需要做自己的同步。

就性能而言,您只需确保最大限度地减少输入的​​块的数量即可。会有差别不大

之间

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

(example B) 
synchronized (originalList) { 
    originalList.add(something); 
} 
,因为它们都进入一个synchronized块。但是:

(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的问题:

在“synchronizedList”例如以C表示,每个呼叫对“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)是学习如何编写线程安全代码的极好资源。我强烈推荐它。我确定它在亚马逊上。