Java ConcurrentModificationException problems with classes - java

I am essentially doing the following:
Creating an object (for example a weapon object), that automatically adds that object to a list off all of those types of objects (ArrayList<Weapons>).
JPanel paints every 10 seconds with an updater thread that iterates through the ArrayList<Weapons>. I am also sending 'questions' to a server on another machine, i.e. asking if that weapon is allowed. If it is not, the weapon object is modified by the client computer. However, whenever I modify it, I receive a ConcurrentModificationException. Instead of crashing, which I actually hope it would do at this point, since the method that changes the weapon object is on a different thread, the whole program just locks up.
I have more than 1000 lines of code in this program, and more than three threads running that access the list, so if you need any code please ask but I'd rather not post right now because in my mind this seems like a trivial question for an expert at threads.
Thanks!
(Object is made >> added to list of objects >> JPanel's "Updater" thread is constantly painting all objects every 10 ticks...
Server says that object isn't allowed >> A thread on the client computer removes that object (or toggles a boolean that says it is not visible) >> ConcurrentModificationException).

Quoting the Javadoc of ArrayList
Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally.
You describe multiple threads accessing the list, and at least one of them modifying it. So, all accesses to the list must be done in mutually synchronized blocks.
e.g. to iterate the list:
synchronized (list) {
for (Weapons weapons : list) {
// ...
}
}
e.g. to remove an item from the list:
synchronized (list) {
list.remove(0);
}

I think you can use a synchronised version of collection or list, i.e. java.util.Collections.synchronizedCollection(Collection<>), java.util.Collections.synchronizedList(List<>). Also, if you iterate over the list and remove items, ensure that use an implementation that enable remove item from the iterator. A good candidate is java.util.ArrayList.
Other technique is use "monitors", you can declare an attribute like: private static Object monitor = new Object(); then when the code tries to access to the list, protect the code inside a synchronized(monitor) block. Using this technique you ensure that no other thread will be able to modify your list until no protected code is running.
Please, excuse my English :).

Related

Adding to ArrayList from separate thread

I have a program with 3 threads (excluding the main thread). The first thread moves an object across the window, the second thread checks for object collisions, and the third is supposed to add to the ArrayList of objects periodically. All three of these threads are manipulating the same list of objects (Though the first 2 are not actually changing the list, just the objects inside). However, when the thread meant to add to the list tries to add an object, I receive an error. Is it possible to manipulate an ArrayList from a different thread?
You can prevent the race conditions by placing the code that manipulates the array list inside synchronized(arrayList) { ... } blocks.
There is nothing special about ArrayList which prevents it from being read and written from multiple threads. However, note the warning in the Javadoc:
Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the list. If no such object exists, the list should be "wrapped" using the Collections.synchronizedList method. This is best done at creation time, to prevent accidental unsynchronized access to the list:
List list = Collections.synchronizedList(new ArrayList(...));
It is also worth reading through the Synchronization Tutorial.
Yes you can handle the array in multiple threads. You can read more in the Java documentation about using the synchronized keyword with objects.
First, If you have a multithreaded application...prefer to use something like Vector instead of ArrayList since ArrayList is not considered thread safe.
Also, for handling concurrency,
You can used make a synchronized method and perform operations to that, or use a synchronized block.

ArrayList vs Vector performance in single-threaded application

I was just looking for the answer for the question why ArrayList is faster than Vector and i found ArrayList is faster as it is not synchronized.
so my doubt is:
If ArrayList is not synchronized why would we use it in multithreaded environment and compare it with Vector.
If we are in a single threaded environment then how the performance of the Vector decreases as there is no Synchronization going on as we are dealing with a single thread.
Why should we compare the performance considering the above points ?
Please guide me :)
a) Methods using ArrayList in a multithreaded program may be synchronized.
class X {
List l = new ArrayList();
synchronized void add(Object e) {
l.add(e);
}
...
b) We can use ArrayList without exposing it to other threads, this is when ArrayList is referenced only from local variables
void x() {
List l = new ArrayList(); // no other thread except current can access l
...
Even in a single threaded environment entering a synchronized method takes a lock, this is where we lose performance
public synchronized boolean add(E e) { // current thread will take a lock here
modCount++;
...
You can use ArrayList in a multithread environment if the list is not shared between threads.
If the list is shared between threads you can synchronize the access to that list.
Otherwise you can use Collections.synchronizedList() to get a List that can be used thread safely.
Vector is an old implementation of a synchronized List that is no longer used because the internal implementation basically synchronize every method. Generally you want to synchronize a sequence of operations. Otherwyse you can throw a ConcurrentModificationException when iterating the list another thread modify it. In addition synchronize every method is not good from a performance point of view.
In addition also in a single thread environment accessing a synchronized method needs to perform some operations, so also in a single thread application Vector is not a good solution.
Just because a component is single threaded doesn't mean that it cannot be used in a thread safe context. Your application may have it's own locking in which case additional locking is redundant work.
Conversely, just because a component is thread safe, it doesn't mean that you cannot use it in an unsafe manner. Typically thread safety extends to a single operation. E.g. if you take an Iterator and call next() on a collection this is two operations and they are no longer thread safe when used in combination. You still have to use locking for Vector. Another simple example is
private Vector<Integer> vec =
vec.add(1);
int n = vec.remove(vec.size());
assert n == 1;
This is atleast three operations however the number of things which can go wrong are much more than you might suppose. This is why you end up doing your own locking and why the locking inside Vector might be redundant, even unwanted.
For you own interest;
vec can change at any point t another Vector or null
vec.add(2) can happen between any operation, changing the size and the last element.
vec.remove() can happen between any operation.
vec.add(null) can happen between any operation resulting in a possible NullPointerException
The vec can /* change */ in these places.
private Vector<Integer> vec =
vec.add(1); /* change*/
int n = vec.remove(vec.size() /* change*/);
assert n == 1;
In short, assuming that just because you used a thread safe collection your code is now thread safe is a big assumption.
A common pattern which breaks is
for(int n : vec) {
// do something.
}
Look harmless enough except
for(Iterator iter = vec.iterator(); /* change */ vec.hasNext(); ) {
/* change */ int n = vec.next();
I have marked with /* change */ where another thread could change the collection meaning this loop can get a ConcurrentModificationException (but might not)
there is no Synchronization
The JVM doesn't know there is no need for synchronization and so it still has to do something. It has an optimisation to reduce the cost of uncontended locks, but it still has to do work.
You need to understand the basic concept to know answer for your above questions...
When you say array list is not syncronized and vector is, we mean that the methods in those classes (like add(), get(), remove() etc...) are synchronized in vector class and not in array list class. These methods will act upon tha data being stored .
So, the data saved in vector class cannot be edited / read parallely as add, get, remove metods are synchornized and the same in array list can be done parallely as these methods in array list are not synchronized...
This parallel activity makes array list fast and vector slow... This behavior remains same though you use them in either multithreaded (or) single threaded enviornment...
Hope this answers your question...

Can objects get lost if a LinkedList is add/remove fast by lots of threads?

sound like a silly question. I just started Java Concurrency.
I have a LinkedList that acts as a task queue and is accessed by multiple threads. They removeFirst() and execute it, other threads put more tasks (.add()). Tasks can have the thread put them back to the queue.
I notice that when there are a lot of tasks and they are put back to the queue a lot, the number of tasks I add to the queue initially are not what come out, 1, or sometimes 2 is missing.
I checked everything and I synchronized every critical section + notifyAll().
Already mark the LinkedList as 'volatile'.
Exact number is 384 tasks, each is put back 3072 times.
The problem doesn't occur if there is a small number of tasks & put back. Also if I System.out.println() all the steps then it doesn't happens anymore so I can't debug.
Could it be possible that LinkedList.add() is not fast enough so the threads somehow miss it?
Simplified code:
public void callByAllThreads() {
Task executedTask = null;
do
{
// access by multiple thread
synchronized(asyncQueue) {
executedTask = asyncQueue.poll();
if(executedTask == null) {
inProcessCount.incrementAndGet(); // mark that there is some processing going on
}
}
if(executedTask != null) {
executedTask.callMethod(); // subclass of task can override this method
synchronized(asyncQueue) {
inProcessCount.decrementAndGet();
asyncQueue.notifyAll();
}
}
}
while(executedTask != null);
}
The Task can override callMethod:
public void callMethodOverride() {
synchronized(getAsyncQueue()) {
getAsyncQueue().add(this);
getAsyncQueue().notifyAll();
}
}
From the docs for LinkedList:
Note that this implementation is not synchronized. If multiple threads access a linked list concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally.
i.e. you should synchronize access to the list. You say you are, but if you are seeing items get "lost" then you probably aren't synchronizing properly. Instead of trying to do that, you could use a framework class that does it for you ...
... If you are always removing the next available (first) item (effectively a producer/consumer implementation) then you could use a BlockingQueue implementation, This is guaranteed to be thread safe, and has the advantage of blocking the consumer until an item is available. An example is the ArrayBlockingQueue.
For non-blocking thread-safe queues you can look at ConcurrentLinkedQueue
Marking the list instance variable volatile has nothing to do with your list being synchronized for mutation methods like add or removeFirst. volatile is simply to do with ensuring that read/write for that instance variable is communicated correctly between, and ordered correctly within, threads. Note I said that variable, not the contents of that variable (see the Java Tutorials > Atomic Access)
LinkedList is definitely not thread safe; you cannot use it safely with multiple threads. It's not a question of "fast enough," it's a question of changes made by one thread being visible to other threads. Marking it volatile doesn't help; that only affects references to the LinkedList being changed, not changes to the contents of the LinkedList.
Consider ConcurrentLinkedQueue or ConcurrentLinkedDeque.
LinkedList is not thread safe, so yes, multiple threads accessing it simultaneously will lead to problems. Synchronizing critical sections can solve this, but as you are still having problems you probably made a mistake somewhere. Try wrapping it in a Collections.synchronizedList() to synchronize all method calls.
Linked list is not thread safe , you can use ConcurrentLinkedQueue if it fits your need,which seems possibly can.
As documentation says
An unbounded thread-safe queue based on linked nodes. This queue
orders elements FIFO (first-in-first-out). The head of the queue is
that element that has been on the queue the longest time. The tail of
the queue is that element that has been on the queue the shortest
time. New elements are inserted at the tail of the queue, and the
queue retrieval operations obtain elements at the head of the queue. A
ConcurrentLinkedQueue is an appropriate choice when many threads will
share access to a common collection. This queue does not permit null
elements.
You increment your inProcessCount when executedTask == null which is obviously the opposite of what you want to do. So it’s no wonder that it will have inconsistent values.
But there are other issues as well. You call notifyAll() at several places but as long as there is no one calling wait() that has no use.
Note further that if you access an integer variable consistently from inside synchronized blocks only throughout the code, there is no need to make it an AtomicInteger. On the other hand, if you use it, e.g. because it will be accessed at other places without additional synchronization, you can move the code updating the AtomicInteger outside the synchronized block.
Also, a method which calls a method like getAsyncQueue() three times looks suspicious to a reader. Just call it once and remember the result in a local variable, then everone can be confident that it is the same reference on all three uses. Generally, you have to ensure that all code is using the same list, hence the appropriate modifier for the variable holding it is final, not volatile.

Java Array list synchronization if written in one thread and read in another

I have a controller class that runs in thread A and composes a local variable list like this
Thread A
list = new ArrayList<Map<String, Order>>();
list.add(...);
list.add(...);
where Order is a java bean with several primitive properties like String, int, long, etc.
Once this list is constructed, its reference is passed to a UI thread (thread B) of Activity and accessed there. The cross-thread communication is done using a Handler class + post() method.
So the question is, can I access the list data from thread B without synchronization at all? Please note, that after constructed in thread A, the list will not be accessed/modified at all. It just exists like a local variable and is passed to thread B afterwards.
It is safe. The synchronization done at the message queue establishes a happens-before relationship. This of course assumes that you don't modify the Maps either afterwards. Also any objects contained in the maps, and so on must not be modified by other threads without proper synchronization.
In short, if the list and none of the data within it are not modified by other threads than B, you don't need any further synchronization.
It is not clear from the context you provide that where does this happen:
list = new ArrayList<Map<String, Order>>();
list.add(...);
list.add(...);
If it is in a constructor and list is final and the this reference does not leak from the constructor and you are absolutely sure that list won't change (for example by using the unmodifiableList decorator method) and the references to the Order instances are not accessible from elsewhere than it may be OK to not use synchronization. Otherwise you have Sword of Damocles over your head.
I mentioned the Order references because you may not get exceptions if you change them from somewhere else but it may lead to data inconsistency/corruption.
If you can guarantee that the list will not be modified then you don't need synchonization since all threads will always see the same List.
Yes, no need to synchronize if you're only going to read the data.
Note that even if thread A is going to eventually modify the list while thread B (or any other number of threads) is accessing it, you still do not have to synchronize because there's only one writer at any given time.
Sorry, the above statement is not completely correct. As stated in the JavaDoc:
If multiple threads access an ArrayList instance concurrently, and at
least one of the threads modifies the list structurally, it must be
synchronized externally. (A structural modification is any operation
that adds or deletes one or more elements, or explicitly resizes the
backing array; merely setting the value of an element is not a
structural modification.)
Also note I'm not taking into account element modification but purely list modifications.

How to Maintain single copy of List among st all threads in Java

class A implements Callable{
List result // want to share this List amongst thread and their function call
public Search call() {
List<Job> Jobs = api. Jobs(a,b,c); // Multiple threads
}
}
class API{
public void jobs(a,b,c){
// want to access the A.Result and populate the result
}
}
How can i share an array List amogst all threds, I dont want to use the Static ,
as it will keep accumilating the result every time it runs ,
Is Thread Local is a good choice over here ?
Trying to avoid an extra object and its respective getters / setters ?
What ever you have right now is thread shared list. All threads operating on this object
(assuming only one instance of this object exists) share same list unless you synchronize.
I know you have your answer, but I did not understand the answer or the question, thus need to ask. So, you problem looks like this? You have a bunch of Callables that will perform some work on a SINGLE list, thus this list is shared among Threads? Then you need to make this List Thread Safe, and making a List of Objects Thread Safe is not that trivial (on your own), unless you use something already given by Java

Categories