1

我正在更新一个旧项目,我想知道是否应该删除一些在 IDE 中标记为“过时”的对象。有问题的对象是 Vector 和 Hashtable。我做了一些研究,似乎这些对象的较新的对应物 - ArrayList 和 HashMap - 基本上是相同的,只是没有同步。

我的问题是,我为什么要切换?我不是只是从我的应用程序中拿走了一点安全性以换取少量的速度吗?无论哪种方式,这似乎都不是一个具有纪念意义的决定,但我想我会在做出决定之前看看是否值得花时间。

谢谢!

4

4 回答 4

11

我不是只是从我的应用程序中拿走了一点安全性以换取少量的速度吗?

如果您唯一的线程安全性依赖于 and 的同步VectorHashtable那么您几乎肯定会遇到麻烦。

通常,更粗粒度的操作需要同步——“同步集合上的每个小操作并希望它足够好”的方法几乎从来都不是必需的,那么为什么要接受它的小打击呢?

如果您在线程之间共享可变数据(例如集合),则需要仔细考虑如何做到这一点 - 使用Vector并且Hashtable会给您一种错误的安全感。

于 2012-06-20T18:08:03.430 回答
2

synchronized会导致显着的性能损失,并且通常不是实现并发的最佳方法。

如果您需要线程安全的集合,请使用java.util.concurrent.

这篇文章可能会有所帮助。

于 2012-06-20T18:10:09.000 回答
1

我不能 100% 确定您是否获得了您认为的“安全”。我通常发现我想自己进行同步,而不是依赖内置的东西(无论是 Vector/Hashtable,还是 Collections.synchronizedList(new ArrayList())/Collections.synchronizedMap(new HashMap())) .

我倾向于更喜欢创建自己的锁定监视器并自己控制所有锁定。如果我不这样做,我往往会忘记锁定复杂的多步骤操作而不会注意到它。我喜欢它如何迫使您考虑系统中的锁定 - 否则实际上您不是很容易“感觉”安全。如果你做的不好,锁定真的会让你一头雾水,成为一堆错误。将锁定放在需要的地方并了解锁定如何保护您自己的访问是值得额外考虑的。

于 2012-06-20T18:16:32.903 回答
0

VectorJava API 的早期类,例如HashtableStringBuffer,被同步以使它们成为线程安全的。不幸的是,同步对性能有很大的负面影响,即使是在单个线程中使用这些集合时也是如此。

最好使用他们新的非同步替换:

  • ArrayListLinkedList代替Vector
  • Deque代替Stack
  • HashMap代替Hashtable
  • StringBuilder代替StringBuffer

代码示例

Vector empList = new Vector();

解决方案

ArrayList empList = new ArrayList();
于 2019-05-17T07:45:11.593 回答