The first thread is filling a collection continuously with objects. A second thread needs to iterate over these objects, but it will not change the collection.
Currently I use Collection.synchronized
for making it thread-safe, but is there a fast way to doing it?
Update
It's simple: The first thread (ui) continuously writes the mouse position to the ArrayList, as long as the mousebutton is pressed down. The second thread (render) draws a line based on the list.
As mentioned in comments, you need explicit synchronization on this list, because iteration is not atomic:
Thread 1:
Thread 2:
Even if you synchronize the list, it's not necessarily thread-safe while iterating over it, so make sure you synchronize on it:
Edit:
Here's a very clearly written article on the matter: http://java67.blogspot.com/2014/12/how-to-synchronize-arraylist-in-java.html
Use java.util.concurrent.ArrayBlockingQueue.ArrayBlockingQueue implementation of BlockingQueue. It perfectly suits your needs.
It is perfectly suited for producer-consumer cases as that is one in yours.
You can also configure access policy. Javadoc explains access policy like this:
There are 3 options which I can currently think of to handle concurrency in ArrayList:-
Using Collections.synchronizedList(list) - currently you are using it.
CopyOnWriteArrayList - behaves much like ArrayList class, except that when the list is modified, instead of modifying the underlying array, a new array in created and the old array is discarded. It will be slower than 1.
Creating custom ArrayList class using ReentrantReadWriteLock. You can create a wrapper around ArrayList class. Use read lock when reading/iterating/looping and use write lock when adding elements in array. For e.g:-
Rather than a
List
will aSet
suit your needs?If so, you can use
Collections.newSetFromMap(new ConcurrentHashMap<>())
If you're reading far more often than writing, you can use CopyOnWriteArrayList