Is it better for two threads to use two lists or one synchronized list?

If you had thread #1 that iterates over a list and uses the data to render 2d graphics, and then thread #2 that is deleting items, adding items, but mostly changing the value of items in that list, which option is better/more efficient?

Option 1:

List<Object> list1 = new ArrayList<Object>();
List<Object> list2 = new ArrayList<Object>();

// Thread 2

ArrayList<Object> newData = new ArrayList<Object>();
newData.add(new Object());

list2 = newData;


// Thread 1

list1 = list2;

for (Object o : list1) {
// use data to render
}

Option 2:

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

// Thread 2

synchronized(list) {
// add, remove, change values
}

// Thread 1

synchronized(list) {
    for (Object o : list) {
    // use data to render
    }
}

I really don’t know a whole lot about this stuff but my fear is that in the second option, thread 1 could be trying to iterate the list and it’s locked so thread 1 runs slow and this is visible because it’s being rendered.

Option 1 is more efficient, but note that on your “list1 = list2” line you must cross a synchronization barrier or you risk your rendering thread reading incomplete data.

You’re correct about option #2 - the technical term for this is “lock contention” and it can be very detrimental to performance.

In general, you could probably improve on both of these patterns, although option #1 isn’t that bad if the list hand-off is properly synchronized (this isn’t unlike the buffer swap chains used to send a rendered image from your GPU to your display).

What’s your intended goal here?

The thread safe queues already provided by the JDK, really.

Anything else will be suboptimal.

Ah okay that’s what I thought, some people were telling me option 2 and somebody told me to use a copyonwritearray even though i said i would be iterating the list every 16 ms and updating the list on the other thread every 20 ms. This is for a client’s data from a server for a multiplayer game. Just out of curiosity would you say this is an advanced topic or pretty basic java stuff?

Push the changes onto a queue from the network thread. Handle however many of them you can from whatever thread is handling them.

Two threads sharing the same list is usually a fundamental design issue.

Edit: and note that CopyOnWriteArrayList is recommended by folks exactly because you say you will be iterating over it a lot. It’s writes that are ‘expensive’ on a copy on write array list because it… copies on write.

Okay, thanks a lot. Lemur gui is great btw :slight_smile:

Thanks.

I also have networking libraries, by the way. :wink:

1 Like

I concur with @pspeed about using the built in queues for this. I find that many “multiple threads sharing data” designs can be easily eliminated by sharing data via queues.

As far as whether this is basic or advanced, I’d generally put anything multithreaded squarely in the advanced category because of the high number of incredibly subtle ways to get into trouble with multiple threads (in any language, not just Java - Java is actually one of the best languages for easier multithreading, in my experience). The best way to safely multithreading is never to do it - the second best way (if you really need multiple threads), is often to use a design where threads only interact via a few well-defined and simply used handoff points (like queues).

1 Like

Okay I’ll read up on that, thank you guys so much

generally i also have one question.

is there some easy way to avoid execution “hard task threads” in same Core as “JME render thread”?

lest say there are 4 Cores, run 3 new “hard task threads”, but sometimes if other application run hard task too, then one of them might go into “render thread core”.

what i thought was just “pausing/dopping thread if fps drop detected”, but it sounds like ugly solution.

so i just ask if someone know good solution to run hard task threads and make them avoid render thread core.

Threads work in cycles of operations. Or time if you prefer. When a thread is not busy it will “give up” that time to another thread. In that way 6 threads can run simoiltaneously - as far as the user is concerned.

If you have four cores and four threads you’re usually fine, but not necessarily as there are always background tasks from within the OS. A good rule of thumb would be core count minus 1 to leave some breathing space, but since the OS and it’s functions are out of your control it’s only an educated guess.

If you are satisfied that your OS overhead is low, thread count - 1 should be perfectly fine. Ignore hyperthreads. They are not real threads. They will use spare cycles, and are great for say encoding but generally useless to count as a “gaming” thread.

1 Like

thread count - 1 should be perfectly fine

well, you might be right, i care too much, it would be “player” issue if he run other process than game process that use cores much.

would just need add FAQ about fps issues.

I made a couple of BlockingQueue<ArrayList<Object>> that thread2 is using to push different kinds of updates to thread1, and thread1 is doing something like while (!blockingQueue.isEmpty()) { every loop, does this look fine? @pspeed

BlockingQueue is dangerous because it will block when full… but maybe that’s desirable.

Pushing whole lists is dangerous because it’s super tempting to keep a local reference to those lists and pretend you can still do something with them.

If you are creating these lists just to push onto the queue then you don’t really have that issue… but then why create the lists?

I keep coming back to the fact that it feels like something a step back from here already has design issues. Like, you’ve painted yourself into a corner and are trying to figure out the best way to get out of the room without smearing the paint.

It’s a list of some updated players, like just really basic things like their x and y. One list is one whole update from the server, and i think just getting really simple things like each players new x and y from the new list and transferring them to the existing list that is used to render should be extremely fast and easily done before each frame, right? but if not, im throwing out all the piled up update lists except for the most recent one, if the server lagged or something. I don’t think I’ve painted myself in a corner, one thread is constantly receiving updated info about the players from the server, and I just need a thread-safe way to transfer that data to the client’s render thread’s lists of data, and i thought this is how you said i should do it

Well, it’s better than nothing. But creating one-off lists just do push them all into a queue at once seems wasteful.

…and if they’re not one-off lists then there is a threading bug.

Note: if you’d rather use prebuilt off-the-shelf and hardened tech for synching objects, you can look at this library:

Examples here:

And an ES (entity component system) version of the example here:

I thought it just made more sense to put all the updated players into a list rather than send them all seperately into the queue, and then on the other side you could distinguish what was one whole update. I’ll take a look at those, thanks again for your help

Yeah, the key takeaway is the above.

One-off lists may seem wasteful but it’s the only way to do what you are proposing (aside from some other custom one-off object). But the key is not to reuse these and to truly create them each time.

Wait so are you saying its fine?