昨天去了某钱公司面试,面试过程中被问道
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还是线程安全的,都是以最终一个线程的数据覆盖了之前的数据。