昨天去了某钱公司面试,面试过程中被问道
Hashtable与HashMap的区别?当时就是回答了一点,Hashtable是线程安全的,HashMap是线程不安全的,说白了,就是Hashtable是的同步的,HashMap不是同步的,需要额外的处理一下。
今天就动手写了一个例子,直接看代码吧
package com.learn.lesson001; import java.util.Hashtable; public class LessonAThread implements Runnable{ public Hashtable<String, String> ht = new Hashtable<String, String>(); public LessonAThread(Hashtable<String, String> ht) { this.ht = ht; } public void run() { System.out.println(); for(int i = 0; i < 20; i++) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() +"-----"+ i); String key = String.valueOf(i); String value = String.valueOf(Thread.currentThread().getName() +"-----"+ i); ht.put(key, value); } } }
测试方法:
package com.learn.lesson001; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; public class TestLesson001 { public static void main(String[] args) { Hashtable<String, String> ht = new Hashtable<String, String>(); HashMap<String, String> hm = new HashMap<String, String>(); for(int i = 0; i < 5; i++) { Thread thread = new Thread(new LessonAThread(ht)); thread.start(); } for (Iterator it = ht.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); String value = ht.get(key); System.out.println(key+":"+value); } } }
结果我可以清晰的看到如下结果:
Thread-0-----0
Thread-4-----0
Thread-2-----0
Thread-1-----0
Thread-3-----0
Thread-4-----1
Thread-2-----1
Thread-1-----1
Thread-0-----1
Thread-3-----1
Thread-1-----2
Thread-3-----2
Thread-4-----2
Thread-2-----2
Thread-0-----2
Thread-3-----3
Thread-4-----3
Thread-1-----3
Thread-0-----3
Thread-2-----3
Thread-1-----4
Thread-4-----4
Thread-3-----4
Thread-2-----4
Thread-0-----4
Thread-1-----5
Thread-3-----5
Thread-4-----5
Thread-0-----5
Thread-2-----5
Thread-4-----6
Thread-1-----6
Thread-3-----6
Thread-0-----6
Thread-2-----6
Thread-1-----7
Thread-3-----7
Thread-4-----7
Thread-0-----7
Thread-2-----7
Thread-4-----8
Thread-1-----8
Thread-3-----8
Thread-0-----8
Thread-2-----8
Thread-4-----9
Thread-1-----9
Thread-3-----9
Thread-2-----9
Thread-0-----9
Thread-4-----10
Thread-1-----10
Thread-3-----10
Thread-0-----10
Thread-2-----10
Thread-4-----11
Thread-1-----11
Thread-3-----11
Thread-0-----11
Thread-2-----11
Thread-4-----12
Thread-1-----12
Thread-3-----12
Thread-0-----12
Thread-2-----12
Thread-3-----13
Thread-1-----13
Thread-4-----13
Thread-0-----13
Thread-2-----13
Thread-4-----14
Thread-1-----14
Thread-3-----14
Thread-0-----14
Thread-2-----14
Thread-3-----15
Thread-4-----15
Thread-1-----15
Thread-2-----15
Thread-0-----15
Thread-4-----16
Thread-1-----16
Thread-3-----16
Thread-2-----16
Thread-0-----16
Thread-2-----17
Thread-0-----17
Thread-4-----17
Thread-3-----17
Thread-1-----17
Thread-3-----18
Thread-4-----18
Thread-0-----18
Thread-2-----18
Thread-1-----18
Thread-3-----19
Thread-4-----19
Thread-2-----19
Thread-0-----19
Thread-1-----19
ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2
JDWP exit error AGENT_ERROR_NO_JNI_ENV(183): [../../../src/share/back/util.c:838]
我想Hashtable应该是加了synchronized,所以启动了五个线程后,共享一个Hashtable,然后有序的往Hashtable中插入数据,
但是不知道为什么没有任何结果输出,请大神解答?
还有那个报错是什么意思?、
ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2
JDWP exit error AGENT_ERROR_NO_JNI_ENV(183): [../../../src/share/back/util.c:838]
感谢二位大神的知道,修改的代码实现如下:
package com.learn.lesson001; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.concurrent.CountDownLatch; public class TestLesson001 { public static final int threadNum = 10; public static final CountDownLatch stopLatch = new CountDownLatch(10*threadNum); public static void main(String[] args) { Hashtable<String, String> ht = new Hashtable<String, String>(); HashMap<String, String> hm = new HashMap<String, String>(); for(int i = 0; i < threadNum; i++) { Thread thread = new Thread(new LessonAThread(ht)); thread.start(); } try { stopLatch.await(); } catch (Exception e) { e.printStackTrace(); } for (Iterator it = ht.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); String value = ht.get(key); System.out.println(key+":"+value); } } }
package com.learn.lesson001; import java.util.Hashtable; public class LessonAThread implements Runnable{ public Hashtable<String, String> ht = new Hashtable<String, String>(); public LessonAThread(Hashtable<String, String> ht) { this.ht = ht; } public void run() { for(int i = 0; i < 10; i++) { try { Thread.sleep(100); System.out.println(Thread.currentThread().getName() +"-----"+ i); String key = String.valueOf(i); String value = String.valueOf(Thread.currentThread().getName() +"-----"+ i); ht.put(key, value); } catch (InterruptedException e) { e.printStackTrace(); }finally { TestLesson001.stopLatch.countDown(); System.out.println(Thread.currentThread().getName() +"=========="+ TestLesson001.stopLatch.getCount()); } } } }
测试结果如下:
9:Thread-6-----9
8:Thread-4-----8
7:Thread-8-----7
6:Thread-4-----6
5:Thread-4-----5
4:Thread-2-----4
3:Thread-6-----3
2:Thread-6-----2
1:Thread-0-----1
0:Thread-0-----0
java.util.concurrent.CountDownLatch即是一个闭锁实现,其内部包含一个计数器,该计数器被初始化为一个整数,表示需要等待事件的数量
countDown方法递减计数器计数,如果计数到达0,则释放所有等待中的线程
await方法使当前线程在计数器倒计数至0之前一直等待,除非等待中的线程中断或等待超时
测试过程中,也将线程数调整1000,最终的结果证明Hashtable还是线程安全的,都是以最终一个线程的数据覆盖了之前的数据。
相关推荐
HashMap和HashTable底层原理以及常见面试题 HashMap和HashTable是Java中两个常用的数据结构,都是基于哈希表实现的,但它们之间存在着一些关键的区别。本文将深入探讨HashMap和HashTable的底层原理,并总结常见的...
HashMap 和 Hashtable 是 Java 中两种常用的哈希表数据结构,它们都是用来存储键值对的数据结构,但它们在设计和实现上有显著的区别。以下是对这两者差异的详细解释: 1. **线程安全性**: - `Hashtable` 是线程...
4. HashMap与Hashtable的区别? 答:HashMap非线程安全,而Hashtable是线程安全的;HashMap允许null键值,Hashtable不允;HashMap迭代器在修改时不会抛出ConcurrentModificationException,而Hashtable会。 5. ...
Hashtable与HashMap类似,也是基于哈希表的,但它在Java早期版本中就已经存在,并且是线程安全的。由于同步机制的存在,Hashtable的性能相比HashMap较低,现在在多线程需求下,通常更推荐使用ConcurrentHashMap,它...
1. HashMap 和 HashTable 的区别 HashMap 和 HashTable都是基于散列表的集合框架,但它们有着不同的设计目标和实现方式。 * HashMap 是非线程安全的,意味着它不能在多线程环境下使用。 * HashTable 是线程安全的...
- HashMap和Hashtable的区别? - HashMap与HashSet的关系? - 如何解决哈希冲突? - 如何自定义键的哈希码生成方式? - 如何避免和处理HashMap中的循环链表? 通过深入学习和理解这些知识点,你将能够在面试中自信...
### HashMap 概述 ...- **线程安全实现**:列举几种使HashMap线程安全的方法。 以上知识点涵盖了HashMap的主要方面,有助于深入理解其工作原理和应用场景。在准备面试或进行技术交流时,这些知识点将非常有用。
2. **ArrayList与Vector的区别,HashMap与Hashtable的区别,Collection与Collections的区别**: - **ArrayList与Vector**: - 同步性:Vector是线程安全的,ArrayList不是。 - 数据增长:Vector默认增长为原来一...
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。 HashMap允许将null作为一个entry的key或者...
8. **HashMap与HashTable的区别**:HashTable是线程安全的,而HashMap不是。此外,HashTable不允许null键和null值,而HashMap允许。 9. **HashMap与TreeMap的选择**:HashMap适用于查找速度快且不关心插入顺序的...
HashMap 和 Hashtable 是 Java 集合框架中两个重要的 Map 实现,它们虽然都是用来存储键值对的数据结构,但在很多方面存在显著的区别。以下将详细分析它们的主要差异、工作原理和适用场景。 1. **线程安全性** - `...
2. Hashtable与HashMap的区别: - 同步性:Hashtable的每个方法都是同步的,而HashMap不是,这使得HashMap更适合在单线程环境中使用,而Hashtable适合在多线程环境中使用。 - 继承关系:Hashtable继承自Dictionary类...
9. **HashMap与HashTable的区别**:HashTable是早期的线程安全版本,但它不允许null键和值,且性能较低,已经被ConcurrentHashMap所取代。 10. **面试常见问题**:面试中常问的问题包括HashMap的扩容机制、哈希冲突...
- **线程安全**:HashTable是线程安全的,适合多线程环境,HashMap不是线程安全的,适用于单线程环境。 - **推荐使用**:由于HashTable不推荐使用,单线程环境下推荐使用HashMap,多线程环境下推荐使用...
- 同步性:HashTable线程安全,HashMap线程不安全。 - 值:HashMap允许null键和值,而HashTable不允许。 6. 垃圾收集(GC): - GC是Java中的自动内存管理机制,它负责识别不再使用的对象并回收它们占用的内存,...
* HashMap 和 Hashtable 的区别:HashMap 允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。 3. Java 字符串操作: * String 和 StringBuffer 的区别:String 类提供了不可改变的字符串,而 ...
- **删除时间复杂度**:与查询时间复杂度类似,理想情况下的删除时间复杂度接近`O(1)`,但在最坏情况下也会退化至`O(n)`。 #### 五、HashMap的底层实现 - **JDK1.8之前**:采用数组+链表的结构。数组用于存储元素...
- HashMap与Hashtable:HashMap非线程安全,而Hashtable是线程安全的,但性能较低,不推荐在现代Java中使用。 - HashMap与HashSet:HashMap存储键值对,HashSet存储元素,两者都基于哈希表,但HashSet是HashMap的...
- **线程安全性**:Hashtable 是线程安全的,而 HashMap 不是。在多线程环境中,若需要线程安全,可以选择 ConcurrentHashMap。 - **空值支持**:HashMap 允许键值为 null,而 Hashtable 不允许。 - **contains 方法...