在一个实现多线程并发的代码中,需要使用一个Map类型的容器来保存某一Socket上连接的用户列表.考虑到线程安全的问题,采用Hashtable是理所应当的选择.但以前错误的以为使用Hashtable了就确保了线程安全,因此仍然按照惯例使用如下的代码对容器内的值进行操作:
Collection keySet = clients.keyset();
Iterator it = keySet.iterator();
while(it.hasNext())
{
Key key = (Key)it.next();
Client client = (Client)clients.get(key);
.......
}
但是系统在实际运行过程中,偶尔会出现漏掉某些client的情况.经过debug,问题定位到上面的代码片段.翻开Jsdk手册,发现对Hashtable的解释里如下一段话:
引用
The Iterators returned by the iterator and listIterator methods of the Collections returned by all of Hashtable's "collection view methods" are fail-fast: if the Hashtable is structurally modified at any time after the Iterator is created, in any way except through the Iterator's own remove or add methods, the Iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the Iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future. The Enumerations returned by Hashtable's keys and values methods are not fail-fast.
原来Hashtable本身虽然线程安全,但是对Hashtable返回的任何形式collection使用Iterator都是会快速失败的!也就是说这个Iterator并不能保证线程安全!!究竟为什么会这样,个人猜测是为了保证Iterator操作的一致性而做的折衷.将上述代码改成
Enumeration enu = clients.kes();
while(enu.hasMoreElements())
{
Key key = (Key)enu.nextElement();
Client client = (Client)clients.get(key);
.......
}
后排除了这个bug.看来,还是得更仔细的研究jsdk了.
分享到:
- 2006-11-09 03:48
- 浏览 2807
- 评论(0)
- 论坛回复 / 浏览 (0 / 3519)
- 查看更多
相关推荐
**Hashtable的使用** 在Java编程语言中,`Hashtable`是一个基于键值对(key-value pairs)的数据结构,它属于同步的、线程安全的容器类。`Hashtable`是`Dictionary`类的一个子类,它不支持`null`键或`null`值。这个...
下面是一个简单的WinForm应用中使用Hashtable的例子: ```csharp public partial class MainForm : Form { private Hashtable controlsData; public MainForm() { InitializeComponent(); controlsData = ...
与此相关的,`Hashtable`是.NET框架中的一个古老的集合类,用于存储键值对,它在早期的.NET应用中十分常见。然而,随着.NET Framework的发展,`Dictionary, TValue>`逐渐取代了`Hashtable`,因为后者不支持泛型,且...
在计算机科学中,哈希表(HashTable)是一种数据结构,它实现了关联数组的抽象数据类型,能够快速地进行查找、插入和删除操作。哈希表通过将键(Key)映射到表中的一个位置来访问记录,从而实现了快速访问。本文将...
在这个例子中,`NoSortHashTable`继承了`Hashtable`,并使用了一个`ArrayList`来存储键的顺序。当添加新元素时,除了在哈希表中添加之外,还会将键添加到`ArrayList`中。当移除元素时,也会同步更新`ArrayList`。...
### 哈希表(Hashtable)的操作使用 #### 哈希表简介 哈希表是一种数据结构,它通过一个称为哈希函数的算法将键(Key)映射到值(Value)。在.NET Framework中,`Hashtable`类是实现哈希表的一个经典示例。它支持...
在ASP.NET中,Hashtable是一种常用的数据结构,它是一个键值对集合,允许程序员存储和检索对象。本篇文章将深入探讨如何在ASP.NET中遍历Hashtable,以及相关的重要知识点。 首先,理解Hashtable的基本概念至关重要...
在Java编程语言中,`Hashtable`是一个非常基础且重要的数据结构,它属于集合框架的一部分,提供了键值对(key-value pairs)的存储功能。`Hashtable`类是线程安全的,意味着在多线程环境下,它能确保数据的一致性和...
2. 性能:HashMap的性能比HashTable好,因为HashMap使用数组和链表来存储键值对,而HashTable使用链表来存储键值对。 3. null键:HashMap允许存放null键和null值,而HashTable不允许存放null键和null值。 常见面试...
在IT行业中,哈希表(HashTable)是一种常用的数据结构,它提供了一种高效的方式来存储和检索数据。在.NET框架中,`Hashtable`是System.Collections命名空间下的一个类,它实现了键值对(Key-Value Pair)存储,允许...
Hashtable是C#编程语言中的一种内置数据结构,属于.NET Framework的System.Collections命名空间。它是一个基于散列的键值对集合,允许程序员快速查找、添加和删除元素。在本篇文档中,我们将深入探讨如何在C#中有效...
`HashTable`通过同步每个方法的执行来实现这一点,即在执行`HashTable`的任何方法时,都会锁定整个对象,确保同一时间只有一个线程能够访问或修改`HashTable`。 - **HashMap**: 相较之下,`HashMap`不是一个线程...
- **HashTable**:使用链表实现,当哈希冲突发生时,使用链表来存储相同哈希值的元素。 6. **历史沿革**: - **HashMap**:是在 Java 1.2 版本中引入的。 - **HashTable**:是早期的 Java 集合框架的一部分,...
在C# .NET编程环境中,`HashTable`类是一个非同步、无序的键值对集合,它提供了快速的数据存储和检索功能。`HashTable`类是基于哈希表数据结构实现的,这使得它能够通过键(key)来快速查找值(value)。在本文中,...
- **HashTable**: 内部使用了`Entry`类来表示键值对,并且每个`Entry`都有一个指向下一个`Entry`的引用。`HashTable`通过计算键的哈希码并将其与表大小取模来确定元素的位置。 - **HashMap**: 与`HashTable`类似,`...
`Hashtable`的所有关键操作(如`put()`、`get()`)都是同步的,这意味着多个线程可以安全地访问同一个`Hashtable`实例而不会引发并发问题。 - **HashMap**: 不是线程安全的。默认情况下,`HashMap`的操作没有进行...
- 如果需要一个线程安全的数据结构来存储键值对,并且不关心键或值是否为null,那么`Hashtable`是一个很好的选择。 - 如果希望拥有更高的性能并能够自己管理线程安全问题,或者需要支持键或值为null的情况,则应该...
在Java中,`HashTable`类是最早的同步容器类之一,它是线程安全的,意味着在多线程环境下可以安全地使用。然而,由于其所有的操作都是同步的,这在单线程环境中可能会导致性能下降。`HashTable`不支持空键和空值,且...
下面是一段使用泛型`Hashtable`的示例代码: ```java import java.util.Hashtable; public class HashtableGenericExample { public static void main(String[] args) { // 创建一个存储String键和Integer值的...
在C#编程中,`Hashtable`是一个非常重要的数据结构,它是.NET框架中提供的一种基于哈希表的键值对集合。本篇文章将深入探讨`Hashtable`在创建通讯录场景中的应用,以及它所涉及的相关知识点。 `Hashtable`是C#中的...