Swair
Swair

Reputation: 1513

how to make a 'modified' ArrayList thread safe in java?

I am implementing a distributed mutex, and I need to keep track of all the requests that have been made.

I've a message class which is comparable and I've a modified ArrayList

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

I suspect that this requestList is getting modified by two threads and I'm seeing elements at the top of the list which should not be there. how do I make this requestList thread safe?

would doing as follows work?

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

also how does Collection.synchronizedList work? by sort of putting a 'synchronized' for all the methods of the ArrayList?

Upvotes: 0

Views: 1165

Answers (1)

Stephen C
Stephen C

Reputation: 718826

would doing as follows work?

No.

Your custom add method is synchronizing on a different object to the requestList object is using to synchronize. Hence, there won't be mutual exclusion.

There is a Collections.synchronizedList method overload that takes a mutex object as an extra parameter. Unfortunately, it is declared as package private, so you won't be able to use it.

so, how do I have a list which IS thread safe, and maintains the sorted order on each add?

There is no simple solution, but a couple of approaches that would work are:

  • Change your code so that the requestList object is private. Implement all access to the list via wrapper methods ... and declare them as synchronized.

  • Write your own custom synchronized list wrapper that can synchronizes on a mutex that is provided to it. Then instantiate the wrapper with your this object as the mutex; i.e. the object that your add method is synchronizing on.

Assuming that your add method is actually part of a "sorted list" wrapper class, the first option is the best one.

The suggestion of using a PriorityBlockingQueue as an alternative to a List is a good one, though you do lose some of the methods that you get in the List API. (For example, you can't do index-based operations on a Queue ...)

Upvotes: 1

Related Questions