如何在java中使'修改'的ArrayList线程安全?

时间:2014-06-29 02:36:19

标签: java multithreading arraylist

我正在实现分布式互斥锁,我需要跟踪已经发出的所有请求。

我有一个可比较的消息类,我已经修改了ArrayList

requestList = new ArrayList<Message>() {
public synchronized boolean add(Message msg) {
    boolean ret = super.add(msg);
    Collections.sort(requestList);
    return ret;
}

我怀疑这个requestList正在被两个线程修改,我看到列表顶部的元素不应该存在。如何使这个requestList线程安全?

会做以下工作吗?

requestList = Collections.synchronizedList(new ArrayList<Message>() {
public synchronized boolean add(Message msg) {
    boolean ret = super.add(msg);
    Collections.sort(requestList);
    return ret;
});

Collection.synchronizedList如何工作?通过点击同步&#39;对于ArrayList的所有方法?

1 个答案:

答案 0 :(得分:1)

  

会做以下工作吗?

没有

您的自定义add方法正在使用同步的requestList对象的另一个对象进行同步。因此,不会互相排斥。

有一个Collections.synchronizedList方法重载,它将互斥对象作为额外参数。不幸的是,它被声明为包私有,因此您无法使用它。

  

那么,我如何获得一个IS线程安全的列表,并在每次添加时保持排序顺序?

没有简单的解决方案,但有两种方法可行:

  • 更改代码,使requestList对象为私有。通过包装器方法实现对列表的所有访问...并将它们声明为synchronized

  • 编写自己的自定义同步列表包装器,可以在提供给它的互斥锁上进行同步。然后使用this对象作为互斥锁实例化包装器;即add方法同步的对象。

假设您的add方法实际上是&#34;排序列表的一部分&#34;包装类,第一个选项是最好的选择。

使用PriorityBlockingQueue作为List的替代方案的建议很好,但您确实丢失了List API中的一些方法。 (例如,您无法在Queue ...)

上执行基于索引的操作