Reputation: 23
I am new to Java, and have come across a problem when trying to implement a simple game. The premise of the game currently is, a timer is used to add a car, and also more frequently to update the movement of the car. A car can be selected by touch, and directed by drawing it's path. The update function will move the car along the path.
Now, the game crashes with an IndexOutOfBoundsException, and I am almost certain this is because occasionally, when a car is reselected, the current path is wiped and it allows a new path to be drawn. The path is stored as a LinkedList, and cleared when the car is touched.
I imagine if the path is cleared via a touch event, whilst the timer thread is updating the cars movement along the path, this is where the error occurs (There are also similar other issues that could arise with two threads accessing this one list.
My question, in Java, what would be the best way of dealing with this? Are there specific types of lists I should be using rather than LinkedList, or are there objects such as a Mutex in c++, where I can protect this list whilst working with it?
Upvotes: 2
Views: 341
Reputation: 328598
Instead of recreating your own thread safe list implementation, you have several built-in options, essentially:
use a synchronized list:
List list = Collections.synchronizedList(new LinkedList());
Note that you need to synchronize on the list (synchronized(list) { }
) for iterations and other combined operations that need to be atomic)
use a thread safe collection, for example a CopyOnWriteArrayList or a ConcurrenLinkedQueue, which could be a good alternative if you don't need to access items in the middle of the list, but only need to add an iterate.
Note that a CopyOnWriteArrayList might have a performance penalty depending on your use case, especially if you regularly add items (i.e. every few microseconds) and the list can become big.
Upvotes: 0
Reputation: 2887
In Java, this is usually accomplished using synchronization
A small example might look something like this:
LinkedList list = //Get/build your list
public void doStuffToList()
{
synchronized(list)
{
//Do things to the list
}
}
public void clearList()
{
synchronized(list)
{
list.clear();
}
}
This code won't let the clear operation be performed if there's another thread currently operating on the list at that time. Note that this will cause blocking, so be careful for deadlocks.
Alternatively, if your List
is a class that you've built yourself, it probably makes sense to make the data structure thread safe itself:
public class SynchroLinkedList
{
//Implementation details
public synchronized void doThingsToList()
{
//Implementation
}
public synchronized void clearList()
{
//Implementation
}
}
These two approaches would effectively work the same way, but with the second one your thread safety is abstracted into the datatype, which is nice because you don't have to worry about thread safety all over the place when you're using the list.
Upvotes: 8