マルチスレッドと高同時-コンテナ6_1:HashTable、SynchronizedHashMap、ConcurrentHashMapの3つのパフォーマンス比較
47063 ワード
Constants package com.inspire.juc.c_023_02_FromHashTableToCHM;
public class Constants {
public static final int COUNT=1000000;
public static final int THREAD_COUNT=100;//100
}
HashTableテスト package com.inspire.juc.c_023_02_FromHashTableToCHM;
import java.util.*;
public class T01_TestHashTable {
static Hashtable<UUID, UUID> m=new Hashtable<>();
static int count=Constants.COUNT;
static UUID[] keys=new UUID[count];
static UUID[] values=new UUID[count];
static final int THREAD_COUNT=Constants.THREAD_COUNT;
static {
for(int i=0;i<count;i++){
keys[i]=UUID.randomUUID();
values[i]=UUID.randomUUID();
}
}
static class MyThread extends Thread{
int start;
int gap=count/THREAD_COUNT;
public MyThread(int start){
this.start=start;
}
@Override
public void run() {
for(int i=start;i<start+gap;i++){
m.put(keys[i],values[i]);
}
}
}
public static void main(String[] args) {
System.out.println(" ");
long start=System.currentTimeMillis();
Thread[] threads=new Thread[THREAD_COUNT];
for(int i=0;i<threads.length;i++){
threads[i]=new MyThread(i*(count/THREAD_COUNT));
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end=System.currentTimeMillis();
System.out.println(end-start);
System.out.println(m.size());
//--------------
System.out.println(" ");
start=System.currentTimeMillis();
for(int i=0;i<threads.length;i++){
threads[i]=new Thread(()->{
for(int j=0;j<1000000;j++){
m.get(keys[10]);// keys[10]100000
}
});
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
end=System.currentTimeMillis();
System.out.println(end-start);
}
}
SynchronizedHashMapテスト package com.inspire.juc.c_023_02_FromHashTableToCHM;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class T03_TestSynchronizedHashMap {
static Map<UUID, UUID> m= Collections.synchronizedMap(new HashMap<UUID,UUID>());
static int count=Constants.COUNT;
static UUID[] keys=new UUID[count];
static UUID[] values=new UUID[count];
static final int THREAD_COUNT=Constants.THREAD_COUNT;
static {
for(int i=0;i<count;i++){
keys[i]=UUID.randomUUID();
values[i]=UUID.randomUUID();
}
}
static class MyThread extends Thread{
int start;
int gap=count/THREAD_COUNT;
public MyThread(int start){
this.start=start;
}
@Override
public void run() {
for(int i=start;i<start+gap;i++){
m.put(keys[i],values[i]);
}
}
}
public static void main(String[] args) {
System.out.println(" ");
long start=System.currentTimeMillis();
Thread[] threads=new Thread[THREAD_COUNT];
for(int i=0;i<threads.length;i++){
threads[i]=new MyThread(i*(count/THREAD_COUNT));
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end=System.currentTimeMillis();
System.out.println(end-start);
System.out.println(m.size());
//--------------
System.out.println(" ");
start=System.currentTimeMillis();
for(int i=0;i<threads.length;i++){
threads[i]=new Thread(()->{
for(int j=0;j<1000000;j++){
m.get(keys[10]);// keys[10]100000
}
});
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
end=System.currentTimeMillis();
System.out.println(end-start);
}
}
ConcurrentHashMapテスト package com.inspire.juc.c_023_02_FromHashTableToCHM;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class T04_TestConcurrentHashMap {
static Map<UUID,UUID> m=new ConcurrentHashMap<>();
static int count=Constants.COUNT;
static UUID[] keys=new UUID[count];
static UUID[] values=new UUID[count];
static final int THREAD_COUNT=Constants.THREAD_COUNT;
static {
for(int i=0;i<count;i++){
keys[i]=UUID.randomUUID();
values[i]=UUID.randomUUID();
}
}
static class MyThread extends Thread{
int start;
int gap=count/THREAD_COUNT;
public MyThread(int start){
this.start=start;
}
@Override
public void run() {
for(int i=start;i<start+gap;i++){
m.put(keys[i],values[i]);
}
}
}
public static void main(String[] args) {
System.out.println(" ");
long start=System.currentTimeMillis();
Thread[] threads=new Thread[THREAD_COUNT];
for(int i=0;i<threads.length;i++){
threads[i]=new MyThread(i*(count/THREAD_COUNT));
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end=System.currentTimeMillis();
System.out.println(end-start);
System.out.println(m.size());
//--------------
System.out.println(" ");
start=System.currentTimeMillis();
for(int i=0;i<threads.length;i++){
threads[i]=new Thread(()->{
for(int j=0;j<1000000;j++){
m.get(keys[10]);// keys[10]100000
}
});
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
end=System.currentTimeMillis();
System.out.println(end-start);
}
}
結論
HashTableとSynchronizedは挿入効率が高く、読み取り効率が低いConcurrentHashMapは挿入効率が低く、読み取り効率が高い
package com.inspire.juc.c_023_02_FromHashTableToCHM;
public class Constants {
public static final int COUNT=1000000;
public static final int THREAD_COUNT=100;//100
}
package com.inspire.juc.c_023_02_FromHashTableToCHM;
import java.util.*;
public class T01_TestHashTable {
static Hashtable<UUID, UUID> m=new Hashtable<>();
static int count=Constants.COUNT;
static UUID[] keys=new UUID[count];
static UUID[] values=new UUID[count];
static final int THREAD_COUNT=Constants.THREAD_COUNT;
static {
for(int i=0;i<count;i++){
keys[i]=UUID.randomUUID();
values[i]=UUID.randomUUID();
}
}
static class MyThread extends Thread{
int start;
int gap=count/THREAD_COUNT;
public MyThread(int start){
this.start=start;
}
@Override
public void run() {
for(int i=start;i<start+gap;i++){
m.put(keys[i],values[i]);
}
}
}
public static void main(String[] args) {
System.out.println(" ");
long start=System.currentTimeMillis();
Thread[] threads=new Thread[THREAD_COUNT];
for(int i=0;i<threads.length;i++){
threads[i]=new MyThread(i*(count/THREAD_COUNT));
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end=System.currentTimeMillis();
System.out.println(end-start);
System.out.println(m.size());
//--------------
System.out.println(" ");
start=System.currentTimeMillis();
for(int i=0;i<threads.length;i++){
threads[i]=new Thread(()->{
for(int j=0;j<1000000;j++){
m.get(keys[10]);// keys[10]100000
}
});
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
end=System.currentTimeMillis();
System.out.println(end-start);
}
}
SynchronizedHashMapテスト package com.inspire.juc.c_023_02_FromHashTableToCHM;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class T03_TestSynchronizedHashMap {
static Map<UUID, UUID> m= Collections.synchronizedMap(new HashMap<UUID,UUID>());
static int count=Constants.COUNT;
static UUID[] keys=new UUID[count];
static UUID[] values=new UUID[count];
static final int THREAD_COUNT=Constants.THREAD_COUNT;
static {
for(int i=0;i<count;i++){
keys[i]=UUID.randomUUID();
values[i]=UUID.randomUUID();
}
}
static class MyThread extends Thread{
int start;
int gap=count/THREAD_COUNT;
public MyThread(int start){
this.start=start;
}
@Override
public void run() {
for(int i=start;i<start+gap;i++){
m.put(keys[i],values[i]);
}
}
}
public static void main(String[] args) {
System.out.println(" ");
long start=System.currentTimeMillis();
Thread[] threads=new Thread[THREAD_COUNT];
for(int i=0;i<threads.length;i++){
threads[i]=new MyThread(i*(count/THREAD_COUNT));
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end=System.currentTimeMillis();
System.out.println(end-start);
System.out.println(m.size());
//--------------
System.out.println(" ");
start=System.currentTimeMillis();
for(int i=0;i<threads.length;i++){
threads[i]=new Thread(()->{
for(int j=0;j<1000000;j++){
m.get(keys[10]);// keys[10]100000
}
});
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
end=System.currentTimeMillis();
System.out.println(end-start);
}
}
ConcurrentHashMapテスト package com.inspire.juc.c_023_02_FromHashTableToCHM;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class T04_TestConcurrentHashMap {
static Map<UUID,UUID> m=new ConcurrentHashMap<>();
static int count=Constants.COUNT;
static UUID[] keys=new UUID[count];
static UUID[] values=new UUID[count];
static final int THREAD_COUNT=Constants.THREAD_COUNT;
static {
for(int i=0;i<count;i++){
keys[i]=UUID.randomUUID();
values[i]=UUID.randomUUID();
}
}
static class MyThread extends Thread{
int start;
int gap=count/THREAD_COUNT;
public MyThread(int start){
this.start=start;
}
@Override
public void run() {
for(int i=start;i<start+gap;i++){
m.put(keys[i],values[i]);
}
}
}
public static void main(String[] args) {
System.out.println(" ");
long start=System.currentTimeMillis();
Thread[] threads=new Thread[THREAD_COUNT];
for(int i=0;i<threads.length;i++){
threads[i]=new MyThread(i*(count/THREAD_COUNT));
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end=System.currentTimeMillis();
System.out.println(end-start);
System.out.println(m.size());
//--------------
System.out.println(" ");
start=System.currentTimeMillis();
for(int i=0;i<threads.length;i++){
threads[i]=new Thread(()->{
for(int j=0;j<1000000;j++){
m.get(keys[10]);// keys[10]100000
}
});
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
end=System.currentTimeMillis();
System.out.println(end-start);
}
}
結論
HashTableとSynchronizedは挿入効率が高く、読み取り効率が低いConcurrentHashMapは挿入効率が低く、読み取り効率が高い
package com.inspire.juc.c_023_02_FromHashTableToCHM;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class T03_TestSynchronizedHashMap {
static Map<UUID, UUID> m= Collections.synchronizedMap(new HashMap<UUID,UUID>());
static int count=Constants.COUNT;
static UUID[] keys=new UUID[count];
static UUID[] values=new UUID[count];
static final int THREAD_COUNT=Constants.THREAD_COUNT;
static {
for(int i=0;i<count;i++){
keys[i]=UUID.randomUUID();
values[i]=UUID.randomUUID();
}
}
static class MyThread extends Thread{
int start;
int gap=count/THREAD_COUNT;
public MyThread(int start){
this.start=start;
}
@Override
public void run() {
for(int i=start;i<start+gap;i++){
m.put(keys[i],values[i]);
}
}
}
public static void main(String[] args) {
System.out.println(" ");
long start=System.currentTimeMillis();
Thread[] threads=new Thread[THREAD_COUNT];
for(int i=0;i<threads.length;i++){
threads[i]=new MyThread(i*(count/THREAD_COUNT));
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end=System.currentTimeMillis();
System.out.println(end-start);
System.out.println(m.size());
//--------------
System.out.println(" ");
start=System.currentTimeMillis();
for(int i=0;i<threads.length;i++){
threads[i]=new Thread(()->{
for(int j=0;j<1000000;j++){
m.get(keys[10]);// keys[10]100000
}
});
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
end=System.currentTimeMillis();
System.out.println(end-start);
}
}
package com.inspire.juc.c_023_02_FromHashTableToCHM;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class T04_TestConcurrentHashMap {
static Map<UUID,UUID> m=new ConcurrentHashMap<>();
static int count=Constants.COUNT;
static UUID[] keys=new UUID[count];
static UUID[] values=new UUID[count];
static final int THREAD_COUNT=Constants.THREAD_COUNT;
static {
for(int i=0;i<count;i++){
keys[i]=UUID.randomUUID();
values[i]=UUID.randomUUID();
}
}
static class MyThread extends Thread{
int start;
int gap=count/THREAD_COUNT;
public MyThread(int start){
this.start=start;
}
@Override
public void run() {
for(int i=start;i<start+gap;i++){
m.put(keys[i],values[i]);
}
}
}
public static void main(String[] args) {
System.out.println(" ");
long start=System.currentTimeMillis();
Thread[] threads=new Thread[THREAD_COUNT];
for(int i=0;i<threads.length;i++){
threads[i]=new MyThread(i*(count/THREAD_COUNT));
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end=System.currentTimeMillis();
System.out.println(end-start);
System.out.println(m.size());
//--------------
System.out.println(" ");
start=System.currentTimeMillis();
for(int i=0;i<threads.length;i++){
threads[i]=new Thread(()->{
for(int j=0;j<1000000;j++){
m.get(keys[10]);// keys[10]100000
}
});
}
for(Thread t:threads){
t.start();
}
for(Thread t:threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
end=System.currentTimeMillis();
System.out.println(end-start);
}
}