java - 线程安全地从一个列表中删除/添加元素到另一个列表

标签 java multithreading list iterator thread-safety

假设我有两个列表:fooList , 和 barList .另外,假设我有两个线程:第一个线程遍历 fooList,如果满足某些条件(条件为真),它会从 fooList 中删除元素并将其添加到 barList。第二个遍历 barList,如果其他条件为真,它从 barList 中删除元素,并将其添加到 fooList。

我的处理方式是:

private static Object sharedLock = new Object();

Thread t1 = new Thread() {
    public void run() {
        synchronized (sharedLock) {

            for (Iterator<String> iterator = fooList.iterator(); iterator.hasNext();) {
                String fooElement = iterator.next();
                if (condition == true) {

                    iterator.remove();
                    barList.add(fooElement);

                }
            }

        }
    }
};

Thread t2 = new Thread() {
    public void run() {
        synchronized (sharedLock) {

            for (Iterator<String> iterator = barList.iterator(); iterator.hasNext();) {
                String barElement = iterator.next();
                if (otherCondition == true) {

                    iterator.remove();
                    fooList.add(barElement);

                }
            }

        }
    }
};

我想知道的是我处理得当吗?有竞争条件的可能性吗?有没有更好的方法来实现相同的功能?

编辑 看起来正确的实现方法是:

Thread t1 = new Thread() {
    public void run() {

        for (String fooElement : fooList) {
            if (condition == true) {

                fooList.remove(fooElement);
                barList.add(fooElement);

            }
        }

    }
};

Thread t2 = new Thread() {
    public void run() {

        for (String barElement : barList) {
            if (otherCondition == true) {

                barList.remove(barElement);
                fooList.add(barElement);

            }
        }

    }
};

其中:fooListbarList类型为 CopyOnWriteArrayList<String>

最佳答案

不要重新发明轮子:使用来自 JDK 的 List 的线程安全实现:

List<String> fooList = new CopyOnWriteArrayList<>();

参见 javadoc

关于java - 线程安全地从一个列表中删除/添加元素到另一个列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26461428/

相关文章:

list - Elixir:生成给定参数出现 `n` 次的列表(类似于 Haskell 的复制)

java - JavaFX 分页中的自动幻灯片放映

java - java在开发中通常会占用所有这些内存吗?

c++ - C++中判断是进程还是线程

c - 11线程程序段错误

c++ - 与调度相关的死锁

java - CI/CD - 在发布分支、管道或源代码构建上标记 jar Artifact ?

java - 任务在服务器上运行时 HTTP 请求超时

c# - 如何: Assign a unique number to every entry in a list?

list - 为什么我要使用 Maybe 而不是 List?