0

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?

9
  • What happened when you tried it? Commented Jun 29, 2014 at 2:41
  • well, its difficult to reproduce the bug. it comes up rarely,I've made the change haven't had the issue still. Commented Jun 29, 2014 at 2:42
  • Hmmm. idk what to say... Also, you can usually find the .java files for the various Java classes somewhere in your JDK installation and/or IDE and/or some online services somewhere. Commented Jun 29, 2014 at 2:52
  • bugs still there. Hmm i'll try looking at some implementations. Commented Jun 29, 2014 at 2:54
  • 1
    I would use a PriorityBlockingQueue. It's thread safe and automatically sorts its elements. Commented Jun 29, 2014 at 3:13

1 Answer 1

1

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 ...)

Sign up to request clarification or add additional context in comments.

5 Comments

"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." - the synchronizedList wrapper (requestList) and the actual list might be synchronizing on different objects, and so the synchronized modifier of add is useless here, but that doesn't mean it won't work.
@immibis - Actually it does mean that it won't work. The sort operation is going to be performed without locking to prevent updates to requestList happening simultaneously. The net result is that those updates could be lost. (Look at how sort works ... )
something calls requestList.add, which is synchronized and calls the OP's add which calls Collections.sort. requestList's monitor is held during the call.
With the code as written, requestList.add CANNOT call the add method that the OP has shown us. Your scenario makes no sense.
requestList = Collections.synchronizedList(new ArrayList<Message>() {public synchronized boolean add(Message msg) {...}}) - either I horribly misunderstand what Collections.synchronizedList does, or you're wrong, or my reasoning is faulty.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.