java - 将synchronizedList与for循环结合使用并在其中添加项目

标签 java multithreading synchronization thread-safety

我正在使用

Collections.synchronizedList(new ArrayList<T>())

部分代码为:

list = Collections.synchronizedList(new ArrayList<T>());

public void add(T arg) {
    int i;
    synchronized (list) {
        for (i = 0; i < list.size(); i++) {
            T arg2 = list.get(i);

            if (arg2.compareTo(arg) < 0) {
                list.add(i, arg);
                break;
            }

        }

for 循环实际上使用迭代器,因此我必须同步包装 for ,这是正确的吗?

像我在这里那样使用同步并在其中进行添加是线程安全的吗?

如果这些问题非常基本,我很抱歉,我是这个主题的新手,在互联网上没有找到答案。 谢谢!!

最佳答案

Is it right that for loop is actually using iterator and therefore I must wrap the for with synchronized?

您的问题分为两个部分。

首先,不,您在这里没有使用迭代器,这是一个基本的 for 循环。

增强的 for 循环是使用迭代器的 for 循环:

for (T element : list) { ... }

您可以看到in the language spec它如何使用迭代器 - 搜索“增强的 for 语句相当于以下形式的基本 for 语句”的位置。

其次,即使您没有使用迭代器,您确实需要同步。两者是正交的。

您正在执行多个操作(sizegetadd),并且它们之间存在依赖关系。您需要确保没有其他线程干扰您的逻辑:

  • get 取决于 size,因为您不想尝试获取 index >= size 的元素,例如实例;
  • add 取决于 get,因为您显然是在尝试确保列表元素是有序的。如果另一个线程可以在您获取元素后潜入并更改该元素,您可能会将新元素插入到错误的位置。

您可以通过list上的同步来正确地避免这种潜在的干扰,创建synchronizedList,除了synchronizedList 可以直接访问底层列表。

关于java - 将synchronizedList与for循环结合使用并在其中添加项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44624622/

相关文章:

java - 在 Java 中组合 6 组 2 个元素

java - 如何使用 JAVA servlet 捕获请求

java - 程序的输出。测试题类型

multithreading - 在 Haskell 中使用共享套接字的多线程

C# 线程 - 锁 - 如何检查锁的发生

java - 将 BigDecimal 转换为 Integer

c++ - 有史以来最简单的互斥量。这个例子行得通吗?它是线程安全的吗?

sql - 为什么 SQL 数据同步需要 SQL Server 本地数据库上的 Alter Database 权限?

winapi - Win32 CRITICAL_SECTION 包含什么?

java - Java RabbitMQ 客户端中的ConfirmListener是否必须同步?