java - 如何同步对不同类成员的访问?

标签 java multithreading thread-safety synchronized

我正在尝试找出如何同步来自不同类的同步列表的读/写访问。

一个小例子:我在一个类ListProvider中有一个同步列表,我在另一个类Filter中访问它。顾名思义,此类根据(内)验证检查 isInvalid 执行一些过滤。

filter 方法首先获取列表引用,然后收集要在临时列表中删除的条目,以免遇到并发修改问题,最后从列表中删除条目:

public class Filter {

    ListProvider listProvider;

    ...

    public void filter() {
        List<String> listProviderList = listProvider.getList();

        List<String> entriesToRemove = new ArrayList<>();

        // collect
        for (String entry : listProviderList)
            if (isInvalid(entry)) {
                entriesToRemove.add(entry);
            }
        }

        // remove
        for (String entry : entriesToRemove) {
            listProviderList.remove(entry);
        }       
    }
}

我的问题:如何确保在 filter 进行读取和写入时没有其他线程修改列表?

如果它是Filter自己的列表,我就会这样做:

synchronized(myList) {
    // collect
    // remove
}

但在这种情况下,我不确定使用什么作为监视器。

最佳答案

but in this case I'm not sure what to use as a monitor.

要为特定任务创建监视器,使用私有(private)最终对象是一个很好的模式:

 private final Object listUpdateLock = new Object();
 ...
 synchronized(listUpdateLock) {
    ...
 }

重要的是要确保 ListProvider私有(private) 并且对列表的所有访问都在 synchronized block 内完成 - 即使仅从中读取。

在这种情况下,您正在更新列表,您可以创建一个临时列表,然后在完成后替换它。不过,我不确定您是否可以使用 ListProvider 做到这一点。然后你可以让列表 volatile

关于java - 如何同步对不同类成员的访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22082106/

相关文章:

java - Spring Mobile - 未应用拦截器?设备为空

java - 连接到远程任务管理器失败。这可能表明远程任务管理器已丢失

c++ - 如何在所有线程中同步一个变量的值?

Java 从多次调用中收集 CompletableFuture 的结果

java - 线程安全唯一编号生成器

java - jsf 中 jsp .tag 文件的模拟是什么,或者如何避免复制和粘贴 jsf/facelets 代码?

java - Java 中匹配映射键

multithreading - 如何在 4 核 CPU : 4 threads or 50 threads? 上更快地进行相同的计算

c# - 我可以从 System.Net.Security.SslStream 获得什么级别的线程安全?

ios - 在后台线程上创建 UIViewController 可以吗?