删除(二进制搜索)并迭代同步列表

时间:2016-08-06 07:43:44

标签: java multithreading swing

我使用ArrayList按顺序存储对象(每个对象都有一个整数形式的唯一ID),并且经常需要根据ID来从列表中删除对象。所以我已经决定迭代器不是可行的方式,因为它根据我的理解线性访问列表,并且考虑到搜索的大小和频率,这是不可行的。

要注意的第二件事是,这是一个多线程环境,其中列表可以迭代(按顺序),而另一个线程可能想要更改内容(删除或添加)。我尝试使用同步方法,但发现以下情况仍然偶尔导致ConcurrentModificationException。

ArrayList<Object> list = new ArrayList<>();

public synchronized void removeFromList(int index)
{
    list.remove(index);
}

public synchronized void addToList(Object o)
{
    list.add(o);
}

public synchronized int findByID(int ID)
{
    //search for item in list
}

public void paint(Graphics g)
{
    synchronized(list)
    {
        for(Object o : list)
        {
            o.render(g);
        }
    }
}

paint方法实际上来自Swing。我的最终实现不涉及Swing,但它是一个有用的测试环境。我仍然需要一个多线程解决方案供以后实现。

我不太确定我是否对同步有所了解,但过去几天我一直拼命想把它拼凑起来。有没有人有任何关于如何解决我的直接问题的建议,甚至更好,一个深入资源的链接(一个小小说的大小很棒!)我可能真的沉溺于Java并发编程?< / p>

2 个答案:

答案 0 :(得分:4)

关于同步:你有synchronized种方法 同步包含对象的列表。 void synchronized method()相当于

void method() {
  synchronized(this) {
    // ...
  }
}

因此,您同步外部类实例和而不是内部list实例。我想这会导致你的异常。

答案 1 :(得分:3)

如果您想要按ID排序并通过ID快速访问的集合,那么TreeMap是最佳选择。

如果您还想要并发访问,可以在更新列表时迭代列表,那么ConcurrentSkipListMap是您的最佳选择。

这样,您无需同步任何内容。