• (二十) 共享模型之工具【JUC】【线程安全集合类】


    一、线程安全集合类概述

     

    线程安全集合类可以分为三大类:
    (1)遗留的线程安全集合如 Hashtable Vector

    (2)使用 Collections 装饰的线程安全集合,如:

    1️⃣Collections.synchronizedCollection

    2️⃣Collections.synchronizedList

    3️⃣Collections.synchronizedMap

    4️⃣Collections.synchronizedSet

    5️⃣Collections.synchronizedNavigableMap

    6️⃣Collections.synchronizedNavigableSet

    7️⃣Collections.synchronizedSortedMap

    8️⃣Collections.synchronizedSortedSet

    (3)java.util.concurrent.*(J.U.C 安全集合)

    重点介绍java.util.concurrent.* 下的线程安全集合类,可以发现它们有规律,里面包含三类关键词:Blocking、CopyOnWrite、Concurrent

    1️⃣Blocking 大部分实现基于锁,并提供用来阻塞的方法

    2️⃣CopyOnWrite 之类容器修改开销相对较重

    3️⃣Concurrent 类型的容器

    Concurrent 类型的容器:

    (1)内部很多操作使用 cas 优化,一般可以提供较高吞吐量

    (2)弱一致性

    1️⃣遍历时弱一致性,例如,当利用迭代器遍历时,如果容器发生修改,迭代器仍然可以继续进行遍历,这时内容是旧的

    2️⃣求大小弱一致性, size 操作未必是 100% 准确
    3️⃣读取弱一致性
    遍历时如果发生了修改,对于非安全容器来讲,使用 fail-fast 机制也就是让遍历立刻失败,抛出 ConcurrentModifificationException ,不再继续遍历

    二、ConcurrentHashMap

    1. 练习:单词计数

    1. public class TestWordCount {
    2. public static void main(String[] args) {
    3. demo(
    4. // 创建 map 集合
    5. // 创建 ConcurrentHashMap 对不对?
    6. () -> new ConcurrentHashMap(8,0.75f,8),
    7. (map, words) -> {
    8. for (String word : words) {
    9. // 如果缺少一个 key,则计算生成一个 value , 然后将 key value 放入 map
    10. // a 0
    11. LongAdder value = map.computeIfAbsent(word, (key) -> new LongAdder());
    12. // 执行累加
    13. value.increment(); // 2
    14. /*// 检查 key 有没有
    15. Integer counter = map.get(word);
    16. int newValue = counter == null ? 1 : counter + 1;
    17. // 没有 则 put
    18. map.put(word, newValue);*/
    19. }
    20. }
    21. );
    22. }
    23. private static void demo2() {
    24. Map collect = IntStream.range(1, 27).parallel()
    25. .mapToObj(idx -> readFromFile(idx))
    26. .flatMap(list -> list.stream())
    27. .collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(w -> 1)));
    28. System.out.println(collect);
    29. }
    30. private static void demo(Supplier> supplier, BiConsumer, List> consumer) {
    31. Map counterMap = supplier.get();
    32. // key value
    33. // a 200
    34. // b 200
    35. List ts = new ArrayList<>();
    36. for (int i = 1; i <= 26; i++) {
    37. int idx = i;
    38. Thread thread = new Thread(() -> {
    39. List words = readFromFile(idx);
    40. consumer.accept(counterMap, words);
    41. });
    42. ts.add(thread);
    43. }
    44. ts.forEach(t -> t.start());
    45. ts.forEach(t -> {
    46. try {
    47. t.join();
    48. } catch (InterruptedException e) {
    49. e.printStackTrace();
    50. }
    51. });
    52. System.out.println(counterMap);
    53. }
    54. public static List readFromFile(int i) {
    55. ArrayList words = new ArrayList<>();
    56. try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("tmp/" + i + ".txt")))) {
    57. while (true) {
    58. String word = in.readLine();
    59. if (word == null) {
    60. break;
    61. }
    62. words.add(word);
    63. }
    64. return words;
    65. } catch (IOException e) {
    66. throw new RuntimeException(e);
    67. }
    68. }
    69. }

    2. * ConcurrentHashMap 原理

  • 相关阅读:
    新能源汽车行业资讯-2022-9-13
    MyBatis原理分析手写持久层框架
    Mysql Explain
    什么是yum源?如何对其进行配置?
    flink-sql所有表连接器-1.14
    java中基本数据类型的最大值最小值理解
    windows下VIM配置c/c++自动补全代码
    【唐山海德教育】职称有哪些?
    【论文复现】——基于多尺度虚拟网格与坡度阈值的机载LiDAR 点云滤波方法
    单例模式c++
  • 原文地址:https://blog.csdn.net/yirenyuan/article/details/128208230