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

 

 

 

 

 

你可能感兴趣的:(面试:Hashtable与HashMap的区别(结合线程))