From 5831c9bdd36c1e80bb39f686d929e17dd5155dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=98=8E=E6=B5=B7?= <173535609@qq.com> Date: Wed, 17 May 2023 01:11:01 +0800 Subject: [PATCH] java current CopyOnWrite --- .../CopyOnWriteArrayListDemo01.java | 53 +++++++++++++++++++ .../CopyOnWriteArraySetDemo01.java | 42 +++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 src/main/java/xyz/xuminghai/copy_on_write/CopyOnWriteArrayListDemo01.java create mode 100644 src/main/java/xyz/xuminghai/copy_on_write/CopyOnWriteArraySetDemo01.java diff --git a/src/main/java/xyz/xuminghai/copy_on_write/CopyOnWriteArrayListDemo01.java b/src/main/java/xyz/xuminghai/copy_on_write/CopyOnWriteArrayListDemo01.java new file mode 100644 index 0000000..0062d8c --- /dev/null +++ b/src/main/java/xyz/xuminghai/copy_on_write/CopyOnWriteArrayListDemo01.java @@ -0,0 +1,53 @@ +package xyz.xuminghai.copy_on_write; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * 2023/5/16 22:30 星期二
+ *

CopyOnWriteArrayList示例01

+ * ArrayList的线程安全变体,其中所有可变操作( add 、 set等)都是通过制作底层数组的新副本来实现的。 + * + * @author xuMingHai + */ +public class CopyOnWriteArrayListDemo01 { + + /** + * 日志记录器 + */ + private static final Logger LOGGER = LoggerFactory.getLogger(CopyOnWriteArrayListDemo01.class); + + /** + * 仅在写入时加锁对副本进行修改,最后将修改后的副本替换为原始数组,最终一致性 + * 适用于对并发时数据的精确度不高,读多写少时使用 + */ + private static final CopyOnWriteArrayList COPY_ON_WRITE_ARRAY_LIST = + new CopyOnWriteArrayList<>(new String[]{"0", "1", "2", "3", "4"}); + + + public static void main(String[] args) { + + // 多线程并发访问修改 + new Thread(() -> { + LOGGER.info("list = {}", COPY_ON_WRITE_ARRAY_LIST); + COPY_ON_WRITE_ARRAY_LIST.set(0, Thread.currentThread().getName()); + LOGGER.info("list = {}", COPY_ON_WRITE_ARRAY_LIST); + }).start(); + + new Thread(() -> { + LOGGER.info("list = {}", COPY_ON_WRITE_ARRAY_LIST); + COPY_ON_WRITE_ARRAY_LIST.set(COPY_ON_WRITE_ARRAY_LIST.size() - 1, + Thread.currentThread().getName()); + LOGGER.info("list = {}", COPY_ON_WRITE_ARRAY_LIST); + }).start(); + + // 遍历的只是快照,而不是最新值 + for (String s : COPY_ON_WRITE_ARRAY_LIST) { + LOGGER.info("s = {}", s); + } + + } + +} diff --git a/src/main/java/xyz/xuminghai/copy_on_write/CopyOnWriteArraySetDemo01.java b/src/main/java/xyz/xuminghai/copy_on_write/CopyOnWriteArraySetDemo01.java new file mode 100644 index 0000000..cec3b27 --- /dev/null +++ b/src/main/java/xyz/xuminghai/copy_on_write/CopyOnWriteArraySetDemo01.java @@ -0,0 +1,42 @@ +package xyz.xuminghai.copy_on_write; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * 2023/5/16 22:51 星期二
+ *

CopyOnWriteArraySet示例01

+ * 一个使用内部CopyOnWriteArrayList进行所有操作的Set 。因此,它具有相同的基本属性: + * 它最适合集合大小通常保持较小、只读操作远远多于可变操作的应用程序,并且您需要防止遍历期间线程之间的干扰。 + * 它是线程安全的。 + * 可变操作( add 、 set 、 remove等)很昂贵,因为它们通常需要复制整个底层数组。 + * 迭代器不支持可变remove操作。 + * 通过迭代器遍历速度很快,不会遇到其他线程的干扰。迭代器依赖于在构造迭代器时数组不变的快照。 + * + * @author xuMingHai + */ +public class CopyOnWriteArraySetDemo01 { + + /** + * 日志记录器 + */ + private static final Logger LOGGER = LoggerFactory.getLogger(CopyOnWriteArraySetDemo01.class); + + /** + * 实现Set接口的CopyOnWriteArrayList + */ + private static final CopyOnWriteArraySet COPY_ON_WRITE_ARRAY_SET = new CopyOnWriteArraySet<>(); + + public static void main(String[] args) { + COPY_ON_WRITE_ARRAY_SET.add("1"); + COPY_ON_WRITE_ARRAY_SET.add("2"); + COPY_ON_WRITE_ARRAY_SET.add("3"); + for (int i = 0; i < 2; i++) { + COPY_ON_WRITE_ARRAY_SET.add("4"); + } + LOGGER.info("set = {}", COPY_ON_WRITE_ARRAY_SET); + } + +}