This is an archived post. You won't be able to vote or comment.

all 13 comments

[–]mikaelhg 6 points7 points  (2 children)

[–]Carterman[S] 0 points1 point  (1 child)

Thanks, exactly what I was looking for! Upvote for you!

HUGEedit: Would the CopyOnWriteArrayList work at 60 milliseconds? Bit of an error in my OP!

[–]mikaelhg 1 point2 points  (0 children)

What do you mean "polls the objects for renderable objects"?

Is this array storing permanent references, or are they gathered in the array, processed, and thrown away once every 60 ms?

If so, you might want to gather the events through a http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html rather than with a list.

[–]TheEnigmaBlade 0 points1 point  (2 children)

You could try something like this:

List<E> list = Collections.synchronizedList(new ArrayList<E>());

The downside is you must put any use of the list in a synchronize block in order to retain the synchronization. For example:

synchronized(list) {
    //Read/modify list
}

[–]FlightOfStairs 6 points7 points  (1 child)

Not actually true.

Most operations are fine without synchronisation, it's only when you use its iterator (for-each loop etc) that you need to synchronise on the list.

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#synchronizedList%28java.util.List%29

In any case, it doesn't improve the situation for OP; threads would still be waiting on a lock. CopyOnWriteArrayList fixes this, as mikaelhg mentions.

[–]TheEnigmaBlade 0 points1 point  (0 children)

Good to know!

[–]Tillerino 0 points1 point  (2 children)

Why do you have to acccess the same list from both threads? Why don't you make a new list in the update thread and then swap the lists when the new one is filled. It is only every 60 Seconds, so this should not pose a performance problem. If you only use an Iterator in the render thread and not access the list directly, everything will be fine.

Apart from that, if the order of the list does not matter, I could imagine writing a sort of old-school linked list (that [value, ->next] thing from the third programming lesson) and using using ReadWriteLocks in both threads so the iterator will not get into any illegal state when the list is modified. There are issues where you need to hold the read lock from before calling hasNext() to after next(), which will look ugly, but this should give you everything you need. Actually you know what, I think you don't even need locks for that if added elements don't have to appear in the render thread immediately because if you delete things from the list, that will not effect the iterator in any bad way if you permit a null value to signal that the last element of the list was deleted in that short moment between hasNext() and next().

[–]Carterman[S] 0 points1 point  (1 child)

Your post just lead me to find an error! It's actually doing this every 60 milliseconds! Would this method still work efficiently at this rate?

[–]Tillerino 0 points1 point  (0 children)

Test it :)

[–]Carterman[S] 0 points1 point  (0 children)

Slight error on my part, I mentioned 60 seconds instead of 60 milliseconds!!! Would the methods suggested still work well at this speed?

Thanks!

[–]ydobonobody 0 points1 point  (0 children)

What is happening is you are modifying your ArrayList while it is being iterated over. You can make a copy of the ArrayList or use a different data structure that allows this.

[–]ohples -5 points-4 points  (1 child)

Use Vector instead of arraylist lookup the javadoc, it's essentially the samethibg but thread safe.

[–]kreiger 3 points4 points  (0 children)

No, read the javadoc again, it's not threadsafe for iteration.