Reputation: 5193
I am writing an OpenGL game and have a list of objects to render in the rendering loop, at the same time, updates from the server update this list of objects to render in a asynchronous task.
If I pause the rendering of the objects while the array gets updated obviously you see that on screen.
Would making a copy of the list, updating that and then copying it back (pause the render) be the best way?
Upvotes: 0
Views: 56
Reputation: 39023
A CopyOnWriteArrayList
will allow multiple threads to access the list at once, as @Egor suggested, but I'm not sure it'll be fast enough.
Both reader and writer will interfere with each other all the time, and your users might notice it.
Give it a try. If it works - great, if not, you should have three copies of the list - one the reader (your rendering loop) accesses, one waiting for the next iteration of the rendering loop and another updated by the writer (the server update thread).
Use the three lists like so:
List<info> _readerList, _waitingList, _writerList;
In your rendering loop:
while(true) {
if(_waitingList!=_readerList)
_readerList = _waitingList
render list
}
In your service update thread:
while(true) {
read data from server
update _writerList
if there were updates {
_waitingList = _writerList
}
}
Before you start rendering, initialize _waitingList
and _writerList
to be two different lists with the same content, and start the loops.
This way you have no locking at all, and your two threads don't interfere with each other. The only point of contact between the two threads is the _waitingList
reference, and both threads change that in one atomic operation.
The down side for this is that you'll have to wait until both the render loop and the server thread complete an iteration before the user sees the result.
CLARIFICATION: It just occured to me that I missed an important point -the writer should create a new list and not reuse the same instance, otherwise after a couple of iterations both reader and writer will use the same list, and you're back to the same old race condition.
Upvotes: 1
Reputation: 40218
Try the CopyOnWriteArrayList, which is a thread-safe version of ArrayList
, which makes it possible to add elements to the list while traversing it.
Upvotes: 3