ConcurrentHashMap与ConcurrentSkipListMap

时间:2015-03-02 10:23:05

标签: java concurrency

我想比较ConcurrentHashMapConcurrentSkipListMap之间的效果。它用于研究目的。结果是结果取决于平台到平台。在我的计算机上,预期阅读测试ConcurrentHashMapConcurrentSkipListMap更有效率。但写作测试表现出更多的表现ConcurrentSkipListMapConcurrentHashMap依赖于哈希表,我认为它应该更快。为什么会这样?

package Concurrency;

import java.util.*;
import java.util.concurrent.*;

abstract class Task implements Callable<Long> {
    protected static Map<Integer, String> map;
    protected int nIteration; 
    protected static int index;
    protected long startTime, endTime;
    private static Random random = new Random();
    private static char[] chars = "abcdefghijklmnopqrstuvwxyz".toCharArray();
    public Task(Map<Integer, String> map, int nIteration) {
        Task.map = map;
        this.nIteration = nIteration;
    }
    protected static synchronized String getNextString() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 5; i++) {
            char c = chars[random.nextInt(chars.length)];
            sb.append(c);
        }
        sb.append(index);
        return sb.toString();
    }
    protected static synchronized int getNextInt() {  return index++; }
    protected static synchronized int getPreviousInt() { return index--; } 
    protected static synchronized int getCurrentInt() { return index; } // It's for test purpose.
    public abstract Long call();
}

class WriterTask extends Task {
    public WriterTask(Map<Integer, String> map, int nIteration) { super(map, nIteration); }
    public Long call() {
        startTime = System.currentTimeMillis();
        while(nIteration-- > 0) {
            map.put(getNextInt(), getNextString());
        }
        endTime = System.currentTimeMillis();
        return (endTime - startTime);

    }
}

class ReaderTask extends Task {
    public ReaderTask(Map<Integer,String> map, int nIteration) { super(map, nIteration); }
    @Override
    public Long call() {
        startTime = System.currentTimeMillis();
        while(nIteration-- > 0) {
            map.remove(getPreviousInt());
        }
        endTime = System.currentTimeMillis();
        return (endTime - startTime);
    }
}

public class FourtyThree {
    private static List<Future<Long>> result = new LinkedList<>();
    private static Map<Integer, String> map;
    //private static String mapName;
    private static Map<String, Double> makeReport(
            int nCycle, int nThreads, boolean isWriter , int nIteration) 
                    throws InterruptedException, ExecutionException {
        Long resultTime = 0L;
        int numberLine = 0;
        double resultAverage;
        StringBuilder sb = new StringBuilder();
        sb.append(map.getClass().getSimpleName());
        sb.append(", Cycle:" + nCycle);
        if(isWriter)
            sb.append(", Test type:Writing");
        else
            sb.append(", Test type: Reading");
        sb.append(", iteration:" + nIteration);
        sb.append(", Threads:" +nThreads);
        for(Future<Long> i : result) {
            resultTime += i.get();
            numberLine++;
        }
        resultAverage = (double)resultTime / (double)numberLine;
        resultAverage = (double)Math.round(resultAverage * 100) / 100;
        sb.append(", Average time:" + resultAverage + " milliseconds");
        return Collections.singletonMap(sb.toString(), resultAverage);

    }
    private static void prepareReading(int nIteration) {
        ExecutorService exec = Executors.newSingleThreadExecutor();
        exec.submit(new WriterTask(map, nIteration));
        exec.shutdown();
    }
    public static Map<String, Double> test( Map<Integer, String> testMap, 
                                            int nCycle,
                                            int nThreads, 
                                            boolean isWriter , 
                                            int nIteration ) 
                                               throws InterruptedException, ExecutionException {

        map = testMap;
        if (!isWriter) 
            prepareReading(nThreads * nIteration);
        ExecutorService exec = Executors.newFixedThreadPool(nThreads);
        List<Callable<Long>> tasks = new LinkedList<>();
        for(int i = 0; i < nThreads; i++) {
            if(isWriter)
                tasks.add(new WriterTask(map, nIteration));
            else
                tasks.add(new ReaderTask(map, nIteration));
        }
        result = exec.invokeAll(tasks);
        exec.shutdown();
        map.clear();
        return makeReport(nCycle, nThreads, isWriter , nIteration);
    }


    public static void main(String[] args) throws InterruptedException, ExecutionException {
        Map<String, Double> results = new LinkedHashMap<String, Double>();
        Collection<Double> resultTime = results.values();
        double time = 0;
        ConcurrentHashMap<Integer, String> map1 = new ConcurrentHashMap<>();
        ConcurrentSkipListMap<Integer, String> map2 = new ConcurrentSkipListMap<>();
        for(int i = 0; i < 5; i++) {
            results.putAll(test(map1, i, 16, false, 1000));
        }
        for(Map.Entry<String, Double> entry : results.entrySet()) {
            System.out.println(entry.getKey());
            time += entry.getValue();
        }
        time = time / (double)resultTime.size();
        time = Math.round(time * 100) / 100;
        System.out.print("Average time for all cycles:" + time);
        System.out.print(", Max time:" + Collections.max(resultTime));
        System.out.print(", Min time:" + Collections.min(resultTime));

    }
}
/* Short report:

*** Reading ***
ConcurrentHashMap, Cycle:4, Test type: Reading, iteration:1 000 000, Threads:2
Average time for all cycles:3530.0, Max time:6817.5, Min time:1625.0

ConcurrentSkipListMap, Cycle:4, Test type: Reading, iteration:1 000 000, Threads:2
Average time for all cycles:4716.0, Max time:9337.5, Min time:1294.0

ConcurrentHashMap, Cycle:4, Test type: Reading, iteration:100 000, Threads:16
Average time for all cycles:528.0, Max time:1064.06, Min time:355.25

ConcurrentSkipListMap, Cycle:4, Test type: Reading, iteration:100 000, Threads:16
Average time for all cycles:1081.0, Max time:1732.75, Min time:330.5

*** Writing ***
ConcurrentHashMap, Cycle:4, Test type:Writing, iteration:1 000 000, Threads:2
Average time for all cycles:12112.1, Max time:18261.5, Min time:9111.5

ConcurrentSkipListMap, Cycle:4, Test type:Writing, iteration:1 000 000, Threads:2
Average time for all cycles:11856.7, Max time:18143.0, Min time:8292.0

ConcurrentHashMap, Cycle:4, Test type:Writing, iteration:100 000, Threads:16
Average time for all cycles:9015.0, Max time:16461.75, Min time:5016.5

ConcurrentSkipListMap, Cycle:4, Test type:Writing, iteration:100 000, Threads:16
Average time for all cycles:8922.68, Max time:12383.31, Min time:6783.13


*/

0 个答案:

没有答案