`
toknowme
  • 浏览: 139918 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

面试:Hashtable与HashMap的区别(结合线程)

阅读更多

昨天去了某钱公司面试,面试过程中被问道

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还是线程安全的,都是以最终一个线程的数据覆盖了之前的数据。

 

 

 

 

 

1
3
分享到:
评论
4 楼 toknowme 2015-05-12  
iq527 写道
toknowme 写道
losfog 写道
for (Iterator it = ht.keySet().iterator(); it.hasNext();) { 
            String key = (String) it.next(); 
            String value = ht.get(key); 
            System.out.println(key+":"+value); 
        } 

这段代码执行的时候,你那些线程还没被调度执行呢



再问一下,如果我想等到上面的5个线程都执行完成后,再执行打印,代码应该写呢?




java.util.concurrent包中的工具类可以帮助你实现你的要求


使用“闭锁(java.util.concurrent.CountDownLatch) ”,效果确实好使,感谢~~
3 楼 iq527 2015-05-12  
toknowme 写道
losfog 写道
for (Iterator it = ht.keySet().iterator(); it.hasNext();) { 
            String key = (String) it.next(); 
            String value = ht.get(key); 
            System.out.println(key+":"+value); 
        } 

这段代码执行的时候,你那些线程还没被调度执行呢



再问一下,如果我想等到上面的5个线程都执行完成后,再执行打印,代码应该写呢?




java.util.concurrent包中的工具类可以帮助你实现你的要求
2 楼 toknowme 2015-05-12  
losfog 写道
for (Iterator it = ht.keySet().iterator(); it.hasNext();) { 
            String key = (String) it.next(); 
            String value = ht.get(key); 
            System.out.println(key+":"+value); 
        } 

这段代码执行的时候,你那些线程还没被调度执行呢



再问一下,如果我想等到上面的5个线程都执行完成后,再执行打印,代码应该写呢?



1 楼 losfog 2015-05-12  
for (Iterator it = ht.keySet().iterator(); it.hasNext();) { 
            String key = (String) it.next(); 
            String value = ht.get(key); 
            System.out.println(key+":"+value); 
        } 

这段代码执行的时候,你那些线程还没被调度执行呢

相关推荐

    HashMap和HashTable底层原理以及常见面试题

    HashMap和HashTable底层原理以及常见面试题 HashMap和HashTable是Java中两个常用的数据结构,都是基于哈希表实现的,但它们之间存在着一些关键的区别。本文将深入探讨HashMap和HashTable的底层原理,并总结常见的...

    java面试题——详解HashMap和Hashtable 的区别

    HashMap 和 Hashtable 是 Java 中两种常用的哈希表数据结构,它们都是用来存储键值对的数据结构,但它们在设计和实现上有显著的区别。以下是对这两者差异的详细解释: 1. **线程安全性**: - `Hashtable` 是线程...

    hashmap面试题_hashmap_

    4. HashMap与Hashtable的区别? 答:HashMap非线程安全,而Hashtable是线程安全的;HashMap允许null键值,Hashtable不允;HashMap迭代器在修改时不会抛出ConcurrentModificationException,而Hashtable会。 5. ...

    第9讲 对比Hashtable、HashMap、TreeMap有什么不同?1

    Hashtable与HashMap类似,也是基于哈希表的,但它在Java早期版本中就已经存在,并且是线程安全的。由于同步机制的存在,Hashtable的性能相比HashMap较低,现在在多线程需求下,通常更推荐使用ConcurrentHashMap,它...

    05.HashMap相关面试题

    1. HashMap 和 HashTable 的区别 HashMap 和 HashTable都是基于散列表的集合框架,但它们有着不同的设计目标和实现方式。 * HashMap 是非线程安全的,意味着它不能在多线程环境下使用。 * HashTable 是线程安全的...

    深入解读大厂java面试必考点之HashMap全套学习资料

    - HashMap和Hashtable的区别? - HashMap与HashSet的关系? - 如何解决哈希冲突? - 如何自定义键的哈希码生成方式? - 如何避免和处理HashMap中的循环链表? 通过深入学习和理解这些知识点,你将能够在面试中自信...

    HashMap 概述 精讲 .md

    ### HashMap 概述 ...- **线程安全实现**:列举几种使HashMap线程安全的方法。 以上知识点涵盖了HashMap的主要方面,有助于深入理解其工作原理和应用场景。在准备面试或进行技术交流时,这些知识点将非常有用。

    java面试题(精简)

    2. **ArrayList与Vector的区别,HashMap与Hashtable的区别,Collection与Collections的区别**: - **ArrayList与Vector**: - 同步性:Vector是线程安全的,ArrayList不是。 - 数据增长:Vector默认增长为原来一...

    java程序员面试题

    HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。 HashMap允许将null作为一个entry的key或者...

    HashMap-面试必过

    8. **HashMap与HashTable的区别**:HashTable是线程安全的,而HashMap不是。此外,HashTable不允许null键和null值,而HashMap允许。 9. **HashMap与TreeMap的选择**:HashMap适用于查找速度快且不关心插入顺序的...

    HashMap 和 Hashtable的区别

    HashMap 和 Hashtable 是 Java 集合框架中两个重要的 Map 实现,它们虽然都是用来存储键值对的数据结构,但在很多方面存在显著的区别。以下将详细分析它们的主要差异、工作原理和适用场景。 1. **线程安全性** - `...

    2014年阿里巴巴java工程师电话面试题目

    2. Hashtable与HashMap的区别: - 同步性:Hashtable的每个方法都是同步的,而HashMap不是,这使得HashMap更适合在单线程环境中使用,而Hashtable适合在多线程环境中使用。 - 继承关系:Hashtable继承自Dictionary类...

    HashMap资料.zip

    9. **HashMap与HashTable的区别**:HashTable是早期的线程安全版本,但它不允许null键和值,且性能较低,已经被ConcurrentHashMap所取代。 10. **面试常见问题**:面试中常问的问题包括HashMap的扩容机制、哈希冲突...

    java面试宝典2021.docx

    - **线程安全**:HashTable是线程安全的,适合多线程环境,HashMap不是线程安全的,适用于单线程环境。 - **推荐使用**:由于HashTable不推荐使用,单线程环境下推荐使用HashMap,多线程环境下推荐使用...

    2022年java面试题.doc

    - 同步性:HashTable线程安全,HashMap线程不安全。 - 值:HashMap允许null键和值,而HashTable不允许。 6. 垃圾收集(GC): - GC是Java中的自动内存管理机制,它负责识别不再使用的对象并回收它们占用的内存,...

    租车面试题答案

    * HashMap 和 Hashtable 的区别:HashMap 允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。 3. Java 字符串操作: * String 和 StringBuffer 的区别:String 类提供了不可改变的字符串,而 ...

    Java集合面试题全集

    - **删除时间复杂度**:与查询时间复杂度类似,理想情况下的删除时间复杂度接近`O(1)`,但在最坏情况下也会退化至`O(n)`。 #### 五、HashMap的底层实现 - **JDK1.8之前**:采用数组+链表的结构。数组用于存储元素...

    一些java面试经验pdf

    - HashMap与Hashtable:HashMap非线程安全,而Hashtable是线程安全的,但性能较低,不推荐在现代Java中使用。 - HashMap与HashSet:HashMap存储键值对,HashSet存储元素,两者都基于哈希表,但HashSet是HashMap的...

    Java 最常见的 208 道面试题:第二模块答案

    - **线程安全性**:Hashtable 是线程安全的,而 HashMap 不是。在多线程环境中,若需要线程安全,可以选择 ConcurrentHashMap。 - **空值支持**:HashMap 允许键值为 null,而 Hashtable 不允许。 - **contains 方法...

Global site tag (gtag.js) - Google Analytics