-2

I have a Java ArrayList, that is being used by 500+ threads simultaneously. For some reason, the synchronization block is not ensuring synchronization on a Java Array List. I known that ArrayLists are non thread-safe, i.e., they are not synchronized. However, I thought that by wrapping the list into a synchronized block I would achieve that. Unfortunately, in rare (but in some situations) two or more threads are entering the synchronized block simultaneously, which is giving me non-deterministic behaviour. Am I missing something? How can I guarantee that my array list (or any other list collection) are completely thread safe throughout 500+ simultaneous threads operating in the array.

There is a related question, (Correct way to synchronize ArrayList in java), but I did not understood its answer. Should I create a Synchronized collection at every "run" of my threads???

Sample:

Thread 1

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

Thread 2

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

Thread n

synchronized (_myList) {
   Iterator it = _myList.iterator();
   ...
}
8
  • 2
    You're synchronizing on _myList but then iterating over _unackedSentQueue... why? If two instances have different _myList references but the same _unackedSentQueue references, that will cause the problem you're seeing. Ideally, you should post a short but complete program demonstrating the problem. Fundamentally you should probably consider using a list implementation designed for this though... Commented Aug 17, 2014 at 7:56
  • This doesn't answer your question, but you could use Vector if you need a synchronized variant of arraylist. Commented Aug 17, 2014 at 7:57
  • 2
    @kviiri: No, that only synchronizes each individual operation - it doesn't help if you're trying to synchronize a whole sequence of operations (like iterating). Commented Aug 17, 2014 at 7:57
  • If this list is used across all 500 threads you may make a similar global object lock Object _unackedSentQueueLock = new Object() then use that for your synchronized locks. Alternatively you could always just synchronize with the list your actually using _unackedSentQueue Commented Aug 17, 2014 at 7:59
  • 1
    Are you at any place calling _myList.wait();? Commented Aug 17, 2014 at 8:25

1 Answer 1

0

Option 1 :

Use a custom lock : Object lock = new Object();

and synchronize things over this lock like :

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

Option 2:

Use java.util.Collections.synchronizedList()

Refer the following code :

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());
                }
            }

        }

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

Comments

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.