【问题标题】:Synchronize block not synchronizing a Java array list同步块不同步 Java 数组列表
【发布时间】:2014-08-17 07:54:57
【问题描述】:

我有一个 Java ArrayList,它同时被 500 多个线程使用。由于某种原因,同步块不能确保 Java 数组列表上的同步。我知道ArrayLists 是非线程安全的,,它们不同步。但是,我认为通过将列表包装到同步块中,我可以实现这一点。不幸的是,在极少数情况下(但在某些情况下)两个或多个线程同时进入同步块,这给了我不确定的行为。我错过了什么吗?如何保证我的数组列表(或任何其他列表集合)在数组中运行的 500 多个同时运行的线程中是完全线程安全的。

有一个相关的问题,(Correct way to synchronize ArrayList in java),但我没有理解它的答案。我应该在线程的每次“运行”时创建一个同步集合吗???

示例:

线程 1

synchronized (_myList) {
   Iterator it = _myList.iterator();
   ...
}

线程 2

synchronized (_myList) {
   Iterator it = _myList.iterator();
   ...
}

线程n

synchronized (_myList) {
   Iterator it = _myList.iterator();
   ...
}

【问题讨论】:

  • 您在_myList 上进行同步,但随后在_unackedSentQueue 上进行迭代...为什么?如果两个实例具有不同的 _myList 引用但相同的 _unackedSentQueue 引用,则会导致您看到的问题。理想情况下,您应该发布一个简短但完整的程序来演示该问题。从根本上讲,您可能应该考虑使用为此设计的列表实现...
  • 这不能回答您的问题,但如果您需要 arraylist 的同步变体,您可以使用 Vector
  • @kviiri:不,这只会同步每个单独的操作 - 如果您尝试同步整个操作序列(如迭代),这将无济于事。
  • 如果此列表用于所有 500 个线程,您可以创建一个类似的全局对象锁Object _unackedSentQueueLock = new Object(),然后将其用于您的同步锁。或者,您可以随时与您实际使用的列表同步 _unackedSentQueue
  • 你在任何地方打电话给_myList.wait();吗?

标签: java concurrency


【解决方案1】:

选项 1:

使用自定义锁: Object lock = new Object();

并通过此锁同步事物,例如:

synchronized(lock) { //operations on array list }

选项 2:

使用java.util.Collections.synchronizedList()

参考以下代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

    public class SynchronizedListExample {

        public static void main(String[] args) {

            List<String> syncList = Collections.synchronizedList(new ArrayList<String>());

            syncList.add("one");
            syncList.add("two");
            syncList.add("three");

            // when iterating over a synchronized list, we need to synchronize access to the synchronized list
            synchronized (syncList) {
                Iterator<String> iterator = syncList.iterator();
                while (iterator.hasNext()) {
                    System.out.println("item: " + iterator.next());
                }
            }

        }

    }

【讨论】:

    猜你喜欢
    • 2012-07-06
    • 2011-12-01
    • 2013-03-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多