HashMap, Hashtable, ConcurrentHashMap
이 컬렉션들은 같은 인터페이스를 이용해 만들었기에 역할은 비슷하지만 조금 조금씩 다르게 구현되어있다.
위의 3가지는 Map 인터페이스를 구현한 컬렉션이다. 따라서 우선적으로 <key, value>구조를 가지게 된다.
Hash Collection 기본 메서드 put(key, value) 해당 컬렉션에 key에 대한 value를 넣어준다.
get(key) key에 해당하는 value를 리턴해준다.
clear()
size() |
HashMap
HashMap은 주요 메소드에 synchronized 키워드가 없다.
그래서 멀티 스레딩에서 동기화 문제에 봉착 할 수 있다.
다른 Hash 컬렉션들과 다르게 key, value에 null을 입력할 수 있다.
package HashTest;
import java.util.HashMap;
import java.util.Map.Entry;
public class HashMapTest {
public static void main(String []args) {
HashMap<String, Integer> hm = new HashMap<>();
// key, value로 입력이 가능
hm.put("hello", 123);
hm.put("world", 345);
// key를 null로 할 수 있고 value도 null로 할 수 있다.
hm.put(null, 555);
hm.put("nullKey", null);
System.out.println(hm.get("world") + "\n");
for(String key : hm.keySet()) {
System.out.println("key :: " + key + " value :: " + hm.get(key));
}
// entrySet 메서드는 key, value를 볼 수 있게 해준다.
for(Entry<String, Integer> s : hm.entrySet()) {
System.out.println(s.getKey() + " " + s.getValue());
}
}
}
345 key :: null value :: 555 key :: nullKey value :: null key :: world value :: 345 key :: hello value :: 123 null 555 nullKey null world 345 hello 123 |
Hashtable
Hashtable은 put, get과 같은 주요 메소드에 synchronized 키워드가 선언 되어 있다.
따라서 동기화에는 걱정이 없으나 sychronized 키워드가 선언되면 속도가 많이 저하된다.
HashMap과 달리 key, value에 null을 허용하지 않는다.
package HashTest;
import java.util.Hashtable;
import java.util.Map.Entry;
public class HashtableTest {
public static void main(String[] args) {
Hashtable<String, Integer> ht = new Hashtable<>();
ht.put("hello", 123);
ht.put("world", 321);
// key, value 각각에 null을 허용하지 않는다.
// ht.put("hello", null);
// ht.put(null, 123);
for(String key : ht.keySet()) {
System.out.println(ht.get(key));
}
for(Entry<String, Integer> entry : ht.entrySet()) {
System.out.println("key :: " + entry.getKey() + " value :: " + entry.getValue());
}
}
}
123 321 key :: hello value :: 123 key :: world value :: 321 |
ConcurrentHashMap
HashMap을 동기화 하기 위해 만든 클래스이다.
HashMap과는 다르게 key, value에 null을 허용하지 않는다.
package HashTest;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentHashMapTest {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> chm = new ConcurrentHashMap<>();
chm.put("crocus", 1323);
chm.putIfAbsent("crocus", 345);
chm.putIfAbsent("code", 345);
for(Entry<String, Integer> entry : chm.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
}
code 345 crocus 1323 |
여기서 putIfAbsent라는 메서드가 있는데
이 메서드는 해당 key가 해시에 존재하면 새로이 넣지 않고 없으면 새로 key,value를 넣어주는 메서드이다.
멀티 스레드 환경에서의 컬렉션 결과
Hashtable, Synchronized HashMap, ConcurrentHashMap, synchronizedMap 4가지는 모두 동기화가 잘 되지만
역시 HashMap는 동기화가 되지 않음을 알 수 있다.
package HashTest;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class HashMain {
private static final int MAX_THREADS = 10;
public static int sum = 0;
private static Hashtable<String, Integer> ht = new Hashtable<>();
private static HashMap<String, Integer> hm = new HashMap<>();
private static HashMap<String, Integer> hmSyn = new HashMap<>();
private static Map<String, Integer> hmSyn2 = Collections.synchronizedMap(new HashMap<String, Integer>());
private static ConcurrentHashMap<String, Integer> chm = new ConcurrentHashMap<>();
public static void main(String[] args) throws InterruptedException {
class tFunc implements Runnable{
@Override
public void run() {
for( int i = 0; i < 10000; i++ ){
String key = String.valueOf(i);
sum++;
ht.put(key, i);
hm.put(key, i);
chm.put(key, i);
hmSyn2.put(key, i);
synchronized (hmSyn) {
hmSyn.put(key, i);
}
}
}
}
Thread[] thread = new Thread[10];
for( int i = 0 ; i < MAX_THREADS; i++ ){
thread[i] = new Thread(new tFunc());
thread[i].start();
}
for(int i = 0 ; i < MAX_THREADS; i++) {
thread[i].join();
}
System.out.println("Hashtable size is "+ ht.size());
System.out.println("HashMap size is "+ hm.size());
System.out.println("ConcurrentHashMap size is "+ chm.size());
System.out.println("HashMap(synchronized) size is "+ hmSyn.size());
System.out.println("synchronizedMap size is "+ hmSyn2.size());
System.out.println(sum);
}
}
Hashtable size is 10000 HashMap size is 10851 ConcurrentHashMap size is 10000 HashMap(synchronized) size is 10000 synchronizedMap size is 10000 98882 |
'Basic > Java' 카테고리의 다른 글
CountDownLatch를 이용한 java 병렬 프로그래밍 (0) | 2019.07.30 |
---|---|
Java에서 Collection이란? (0) | 2019.07.13 |
콜백(Callback) 그리고 리스너(Listener) (0) | 2019.06.30 |
객체지향 언어(Object Oriented Language)의 특징 (0) | 2019.06.18 |
Eclipse 설치 및 Open JDK 1.8 설치 (0) | 2019.06.15 |