-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();
   ...
}
Community
  • 1
  • 1
Marcos Roriz Junior
  • 4,076
  • 11
  • 51
  • 76
  • 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... – Jon Skeet Aug 17 '14 at 07:56
  • This doesn't answer your question, but you could use `Vector` if you need a synchronized variant of arraylist. – kviiri Aug 17 '14 at 07: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). – Jon Skeet Aug 17 '14 at 07: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` – ug_ Aug 17 '14 at 07:59
  • Sorry, I forgot to change _unackedSentQueue to _myList (to make the smaple easier). In fact, I am synchronizing with _myList (_unackedSentQueue). – Marcos Roriz Junior Aug 17 '14 at 08:09
  • 1
    Are you at any place calling `_myList.wait();`? – Boann Aug 17 '14 at 08:25
  • Also, if you are using this ArrayList as a queue, are you aware that ArrayBlockingQueue exists, and is already fully thread-safe? – Boann Aug 17 '14 at 08:30
  • Post the code with the problem. Don't just post meaningless snippets. – user253751 Aug 17 '14 at 08:32

1 Answers1

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

        }

    }
Sagar D
  • 2,588
  • 1
  • 18
  • 31