【JUC】ConcurrentHashMap之computeIfAbsent

ConcurrentHashMap之computeIfAbsent

ConcurrentHashMap的锁粒度更细
锁的是桶中的元素,并且只锁表头元素

public class TGestWordCount {
    public static void main(String[] args) {
        demo(
                () -> new ConcurrentHashMap<String, LongAdder>(),
                (map, words) -> {
                    for(String word:words){
                        // 如果缺少这个key, 就根据后面的函数接口返回一个value 并放入map中,
                        // 如果有,则返回这个value
                        LongAdder value = map.computeIfAbsent(word, (key) -> new LongAdder());
                        // 第一次时 value是new出来的, 第二次以后, 是返回map中那个存在的LongAdder对象。
                        // 累加器进行累加
                        value.increment();
                        // map.put(word, map.getOrDefault(word, 0) + 1);
                    }
                }
        );
    }

    private static <V> void demo(Supplier<Map<String, V>> supplier, BiConsumer<Map<String, V>, List<String>> consumer) {
        Map<String, V> counterMap = supplier.get();
        List<Thread> ts = new ArrayList<>();
        for (int i = 1; i <= 26; i++) {
            int idx = i;
            Thread thread = new Thread(() -> {
                List<String> words = readFromFile(idx);
                consumer.accept(counterMap, words);
            });
            ts.add(thread);
        }

        ts.forEach(Thread::start);
        ts.forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println(counterMap);
    }

    private static List<String> readFromFile(int idx) {
        ArrayList<String> words = new ArrayList<>();
        try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("tmp/" + idx + ".txt")))) {
            while (true) {
                String word = in.readLine();
                if (word == null) {
                    break;
                }
                words.add(word);
            }
            return words;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}

点击查看测试案例生成代码
public class TestSampleForCountAlpha {
    static final String ALPHA = "abcedfghijklmnopqrstuvwxyz";

    public static void main(String[] args) {
        int length = ALPHA.length();
        int count = 200;
        ArrayList<String> list = new ArrayList<>(length * count);
        for (int i = 0; i < length; i++) {
            char ch = ALPHA.charAt(i);
            for (int j = 0; j < count; j++) {
                list.add(String.valueOf(ch));
            }
        }
        Collections.shuffle(list);
        for (int i = 0; i < 26; i++) {
            try (PrintWriter out = new PrintWriter(
                    new OutputStreamWriter(
                            new FileOutputStream("tmp/" + (i+1) + ".txt")))) {
                String collect = list.subList(i * count, (i+1) * count).stream()
                        .collect(Collectors.joining("\n"));
                out.print(collect);
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
posted @ 2024-11-28 15:23  chendsome  阅读(61)  评论(0)    收藏  举报