Multi threaded game - updating, rendering, and how to split them - java

So, I'm working on a game engine, and I've made pretty good progress. However, my engine is single-threaded, and the advantages of splitting updating and rendering into separate threads sounds like a very good idea.
How should I do this? Single threaded game engines are (conceptually) very easy to make, you have a loop where you update -> render -> sleep -> repeat. However, I can't think of a good way to break updating and rendering apart, especially if I change their update rates (say I go through the update loop 25x a second, and have 60fps for rendering) - what if I begin updating halfway through a render loop, or vice versa?

Place your update logic in some kind of Updater worker class (implementing Runnable), and put renderer into separate worker class. When you need to update data, let Updater put that update into queue shared by both Updater and Producer. Most convenient would be to use queue which already have built-in multi-threaded support, like subclass of BlockingQueue. For example code, see javadoc for BlockingQueue.
Using queue is natural if you need to render all changes, even obsolete ones. If you wish to render only the latest change, use ConcurrentHashMap instead of queue.
Don't forget to make your updates immutable objects, so there's no chance update can change while you render it.
As Nirmal pointed out, you could use some kind of thread pool to limit number of threads and to simplify starting/stopping of threads. Refer to Executor interface and Executors utility class in JDK to see available options here.

I would suggest going pipeline with this architecture, meaning that the render stage will render all the elements updated on the previous frame, it would go like this:
Update 0
Update 1 Render 0
Update 2 Render 1
Update 3 Render 2
....
it would mean that your game will use more memory and all the objects will have to have per frame states / data
if you introduce more layers in this pipeline your game will suffer from input lag (meaning the user will see his action on the screen later then normal), so I suggest to using just this 2 stage pipeline

create pojo for every category, one runnable object contains data like fps rate, UI screen class n all requited information, you can make common information singleton, so at every time rendering start thread for updating, i recommend threadpool to keep memory consumption limited

Also note that your draw thread should never run faster then your update thread. Since if your update thread is not done with the current step yet, you will draw the same thing as before. While doing this you might miss the finishing of the update step, which in the end causes lower than optimal framerate.
(Remember drawing the exact same picture as before doesn't benefit anyone).

I've made my program using three threads (though more could be used).
Update logic (Does the data collecting and pre-processing)
Helper thread (Calculates time consuming cache pre calculations etc. at infinite sleep 1ms loop ... So this thread does not care where Update logic is going, or how fast. It just checks where it is going and calculates iF it needs to cache new items)
Render thread (Does ONLY rendering, everything it needs to render is pre-processed so it does only draw functions and calculates screen positions)
Doing this is super easy if you just have "thread safe" items you are drawing. But in game, I personally think that it is not bad thing if you render player 1 one tick ahead than player 2... Because you still want to draw as fast you can on games. Game logic thread makes sure there is no logical exceptions... So usually I think it does not matter what you draw and when, you just do it as fast as you can without thinking any "synchronizations".
I presonally prefer public static volatile item to share data between threads. And AtomicIntegerArray is a useful class for that too.

I would say add a field that specifies the thread needed to run and render, and number the threads, if the thread number == the thread required, then it is allowed to run and render, and increment the required thread field, until it hits max, then loop back to 0. Alternatively, you could, use one thread for tick and another for render, this might be easier. Here is an example code:
public Game() {
this.tickThread=new Thread(this::tickLoop());
this.renderThread=new Thread(this::renderLoop());
}
public void tickLoop() {
//code for timing...
while(running) {
//more code for timing...
tick();
}
}
public void renderLoop() {
//code for timing or syncing frames...
while(running) {
//more code for timing...
render();
}
}
Alternatively, you could say:
|MyRunnable.java|
public interface MyRunnable
{
public abstract void run(boolean toRender);
}
|MyThread.java|
public class MyThread extends Thread
{
private boolean isRender;
private MyRunnable runnable
public MyThread(boolean isRender,MyRunnable runnable)
{
this.isRender=isRender;
this.runnable=runnable;
}
public void run()
{
this.runnable.run(this.isRender);
}
}
|Game.java|
public class Game extends /*JPanel/Canvas/JFrame/Some other component*/
{
private MyThread tickThread;
private MyThread renderThread;
private boolean running;
public Game()
{
super();
tickThread=new MyThread(this::run);
renderThread=new MyThread(this::run);
//other constructor code
}
public void tick()
{
//tick code here
}
public void render()
{
//render code here
}
public void run(boolean isRender)
{
//timing variables
while(running)
{
//timing code
if(isRender)
{
this.render();
}
else
{
this.tick();
}
}
}
}

Related

java thread immediately update UI

I have a javaFX application which visualizes compuational geometry algorithms. The execution of an algorithm happens in another thread, lets call it mainComputingThread.
An algorithm can update the UI at any time by adding/removing/modifying shapes.
so the code will look like:
//do some computaions (1)
updateUI();
//do some more calculations (2)
What I want know is in the updateUI method to update the UI immediately and prevent the calling thread from running further (marked as (2)) until the UI update is done.
I thought about boolean guards. So the code could would look like:
updateUI(){
boolean guard = false;
Platform.runLater(new Runnable()
{
run(){
//do the actual update
guard = true;
}
});
while(guard==false);
}
I hope you get an idea of what I mean. I'm really curious if there's a better solution for this problem...
Simple approach: block background thread until update is complete:
You need to update the UI on the FX Application Thread. Typically you do this by passing a plain Runnable to Platform.runLater(...).
If you want to wait for that ui update to complete before proceeding, instead create a FutureTask and pass it to Platform.runLater(...). Then you can call get() on the FutureTask, which will block until the task is complete:
private void updateUI() throws InterruptedException {
// actual work to update UI:
FutureTask<Void> updateUITask = new FutureTask(() -> {
// code to update UI...
}, /* return value from task: */ null);
// submit for execution on FX Application Thread:
Platform.runLater(updateUITask);
// block until work complete:
updateUITask.get();
}
This lets the FutureTask handle all the tricky work of waiting and notifying: it is always better to use a higher-level API for this kind of work when you can.
If you like, you can refactor this into a utility method, similarly to Dainesch's answer:
public class FXUtils {
public static void runAndWait(Runnable run) throws InterruptedException {
FutureTask<Void> task = new FutureTask<>(run, null);
Platform.runLater(task);
task.get();
}
}
Alternative approach: ensure that no more than one update is consumed during any frame rendering, blocking the background thread if an update is pending
Here is a somewhat different approach. Create a BlockingQueue with a capacity of 1 to hold the Runnables that update the UI. From your background thread, submit the Runnables to the blocking queue: since the blocking queue can hold at most one element, this will block if one is already pending.
To actually execute the updates in the queue (and remove them, so more can be added), use an AnimationTimer. This looks like:
private final BlockingQueue<Runnable> updateQueue = new ArrayBlockingQueue<>(1);
background thread code:
// do some computations...
// this will block while there are other updates pending:
updateQueue.put(() -> {
// code to update UI
// note this does not need to be explicitly executed on the FX application
// thread (no Platform.runLater()). The animation timer will take care of that
});
// do some more computations
Create the timer to consume the updates:
AnimationTimer updateTimer = new AnimationTimer() {
#Override
public void handle(long timestamp) {
Runnable update = updateQueue.poll();
if (update != null) {
// note we are already on the FX Application Thread:
update.run();
}
}
};
updateTimer.start();
This basically ensures that no more than one update is ever scheduled at any time, with the background thread blocking until any pending updates are consumed. The animation timer checks (without blocking) for pending updates on each frame rendering, ensuring that every update is executed. The nice thing about this approach is that you can increase the size of the blocking queue, effectively keeping a buffer of pending updates, while still ensuring no more than one update is consumed during any single frame rendering. This might be useful if there are occasional computations that take longer than others; it gives these computations a chance to be calculated while others are waiting to be executed.
Hard question to answer without having the reason why you want to stop processing before the UI update is done. (Note: the runLater method executes the UI updates in the order received) Is it to prevent spamming to many Runnables to the JavaFX thread? Other reasons?
Your basic idea however works with the use of a CountDownLatch so that the processing thread waits to acquire a permit. If you choose that approach use something like this:
public class MyFXUtils {
public static runAndWait(final Runnable run) {
final CountDownLatch doneLatch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
public void run() {
try {
run.run();
} finally {
doneLatch.countDown();
}
}
});
doneLatch.await();
}
}
EDIT: replaced Semaphore by CountDownLatch
EDIT:
So, the quickest way I always do it in prototypes is as following, transform:
//do some computaions (1)
updateUI();
//do some more calculations (2)
into
ExecutorService executor = Executors.newFixedThreadPool(1);
class JobStep implements Runnable {
public void run() {
doSomeComputations();
Platform.runLater(() -> {
updateUI();
executor.submit(new JobStep());
});
}
executor.submit(new JobStep());
OLD PART
Not an answer, but a suggestion how to attack the problem.
From my experience, the complete solution would be much more elaborate. I would separate the JavaFX shape instances from the shapes, which your algorithm does process. I would do it by means of using different class types and synchronize between the two.
The graphical algorithms have the tendency to be a lot quicker than the ones that are visualizing it. If the algorithm runs on small data set, then the rendering most often tend to slow down it significantly. It can easily be seen by running the same algorithm with and without visualization.
If the data set is bigger than the most trivial ones, then drawing of a single frame can easily take more than one second. Interactive visualizations are expected to respond in "real time", preferably many times per second.
The data visualization facilities have many means to tackle the problem. The best candidates always include:
Simplifying visualization. Drawing simpler shapes instead of complex, like removing the rounding from boxes. The LOD (level of detail) also applies to this point: during interactive scroll the visualized elements might be replaced by bounding box counterparts.
Selective hiding. Drawing only a part of the whole data set.
Parallelizing and hardware acceleration. The GPU's natively provide many means to handle complex visualizations. Typically the low level programming APIs (OpenGL, shader programs) allow much better throughput than every high level wrapping API, including JavaFX
Most often, the end solutions incorporate not only above points, but also others, including domain specific optimizations.
The visualization facilities always come with a lot of restrictions, like the most common one: have to be updated in the dedicated thread (thread confinement approach). They also come with visualization specific data structures.
From the data processing algorithm stage, one of the most common requirements is that it cannot be blocked or delayed by visualization. The algorithms are also written in a style, which doesn't translate to well for the means of visualization: imperative loops over data structures instead of updating observable drawable objects. There is a good reason to it though: the algorithms are expected to be optimized for performance or memory consumption.
One architectural approach to the problem might be as following:
The data processing stage produces snapshots at predefined points. The adding, modifying and remove operations are all published as this packet. It can be a just a copy of data structure that is being processed or it can be in the form of the coalesced events.
The data processing and data visualization run on different threads. They communicate only by means of publishing snapshots, never by blocking each other directly.
The snapshots shouldn't be restricted to particular frame rate. There should be means to batch updates before drawing or drawing same batch multiple times if the data processing stage stalls.
I strongly recommend reactive approach to the problem. The RxJava provides nice example for the "suggestion box" feature. It's very good at correctly handling requirements like "Every key update do a long running process on different thread and discard the last one, if any was running. Or maybe, don't do it on every key update, but wait 50ms for the user to make up his mind before he ends typing".

Is this a good approach for threading and synchronization of multiple functions of a Java class?

I have a class Prefs, which has various methods. I need to rewrite it using threading and synchronization.
I'm looking at this variant: http://tutorials.jenkov.com/java-concurrency/synchronized.html
So currently:
class T_readConfigFile extends Thread {
protected Prefs p = null;
public T_readConfigFile(Prefs p) {
this.p =p;
}
public void run() {
p.readConfigFile();
}
}
and
public synchronized void readConfigFile() { ...
But somehow making N identical classes for each of the methods I want to thread doesn't look like a good idea. I assume it the entire class in this.p = p; gets loaded into memory — do I really need that if I'll be using only one method from there?
So: this works, but I don't like it, are there better ways?
Suppose you want to call some method foo() in a background thread. You have already discovered the most basic way. Here's a somewhat preferable variation on what you did:
new Thread(new Runnable() {
#Override
public void run() {
foo();
}
}).start();
OK, so I wrote six lines of Java code to call one function. Yes, that's kind of verbose. Welcome to Java (or at least, Welcome to Java7. If it can be done more concisely in Java8, I haven't yet learned how.)
This approach has a couple of problems that are worse than verbosity though:
1) You create and destroy a new thread each time you want to call a background method. Creating and destroying threads is relatively expensive.
2) If the background tasks take significant time to perform relative to how often you invoke them, you have no means to control the number of them that are running at the same time. In a busy application, it could keep growing until you get an OutOfMemoryError.
A better approach is to use a thread pool:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
...
final int NUM_THREADS = ...;
final ExecutorService executorService = Executors.newFixedThreadPool(NUM_THREADS);
...
executorService.submit(new Runnable() {
#Override
public void run() {
foo();
}
});
Each time you submit a new task to the thread pool, it will wake an already existing thread, and the thread will perform the task and then go back to sleep. No threads are created or destroyed except when the pool starts up.
Also, if all of the threads are busy when you submit the new task, the task will be added to a queue, and it will be performed later when a worker thread becomes available.
This is just a simple example: The java.util.concurrent package gives you many more options including the ability to limit the size of the queue, the ability to make thread pools that grow or shrink depending on demans, and perhaps most important of all, the ability to wait for a task to complete, and a way to get a return value from a completed task.
Check it out. http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-frame.html
A synchronized method locks the method's class object so that only one thread can be executing that method at a time. This is useful for situations where you don't want multiple threads to be reading or writing to the same file or stream at the same time, for example.
If you need each thread to read its own separate configuration file, you probably don't need to synchronize the readConfigFile() method. On the other hand, you do need to synchronize it if every thread reads the same config file.
But if all of the threads are reading the same config file, perhaps you should only have one thread (or perhaps the main parent thread) read the file once, and then pass the resulting parsed config values to each thread. This saves a lot of I/O.

What's proper way to make my own events in java

I'm student and I'm working on project with few of my friends. My task is to make something like class library. Classes in this library should provide API for my friend who must make GUI part of application. GUI could be made by any toolkit (Swing, JavaFX, SWT, AWT, all should work, in fact, it should work even if there is no GUI). I need to make class that waits for data to arrive from network. I don't know when data will arrive, and UI must be responsive during waiting, so I put that in different thread. Now problem is how to make GUI respond when data arrive. Well, I tought that this is asynchronous event and GUI should register event handlers, and I should call that methods when event happens. I proposed this solution:
interface DataArrivedListener{
void dataArrived(String data);
}
class Waiter{
private DataArrivedListener dal;
public void setDataArrivedListener(DataArrivedListener dal){
this.dal = dal;
}
void someMethodThatWaitsForData(){
// some code goes here
data = bufRdr.readLine();
//now goes important line:
dal.dataArrived(data);
// other code goes here
}
}
My question is:
Should I replace "important" line with something like this:
java.awt.EventQueue.invokeLater(new Runnable(){
#Override
public void run(){
dal.dataArrived(data);
}
});
Or something like:
javafx.Platform.runLater(new Runnable(){
#Override
public void run(){
dal.dataArrived(data);
}
});
Or maybe I should do something completely different?
Problem is that I'm not sure which of this will work for any type of UI. If it's GUI, dataArrived() could potentialy make changes to GUI and no matter what type of GUI it is, this changes should be drawn on screen properly. I also think that it is better if I do "invoke this code later" so that my someMethodThatWaitsForData() method could trigger event and continue on with it's on work.
I appreciate your help.
Here's an Event Listener article I wrote a while back. The article explains how you write your own event listeners.
You're correct in that you want to write your own event listeners if you want your library to work with any GUI.
I'm most familiar with Swing, so yes, you'll have GUI code that looks like this:
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent event){
dal.buttonPressed(data);
}
});
If you want it to be completely agnostic to what GUI is being used the only real solution is to let the receiver handle it in dataArrived. Since every toolkit has its own implementation all you can really do to make it work with any toolkit is to disregard it. Otherwise what you will actually end up with is a list of "supported toolkits" and a case for each one.
If you just want dataArrived to be executed away from someMethodThatWaitsForData then you could make your own dispatch thread or make a new thread each time.
If you want to be truly independent of any front-end system, I would recommend creating two threads. The first is your Waiter, which will just listen for events and put them into a Queue of some sort (see the "All Known Implementing Classes" section). The second will invoke the data listener or listeners whenever the queue is not empty.
The concept of invoking a Runnable in the background is kind of deprecated since the invention of the concurrent package. The main reason that this was done in earlier days, is that the GUI code needs to be executed in a different thread, to guarantee that it stays responsive, even if the main thread is busy doing some calculations, but actual multi-threading was still in its very early days. The resulting invokeLater concept works, but comes with a strong creation overhead. This is especially annoying if you frequently have to do minor things, but each time you need to create an entire new Runnable, just to get that event into the Swing thread.
A more modern approach should use a thread-safe list, like a LinkedBlockingQueue. In this case any thread can just throw the event into the queue, and other listener/GUI-Event-handlers can take them out asynchronously, without the need of synchronization or background Runnables.
Example:
You initialize a new Button that does some heavy calculation once it is pressed.
In the GUI thread the following method is called once the button is clicked:
void onClick() {
executor.submit(this.onClickAction);
}
Where executor is an ExecutorService and the onClickAction a Runnable. As the onClickAction is a Runnable that was submitted once during Button creation, no new memory is accessed here. Let's see what this Runnable actually does:
void run() {
final MyData data = doSomeHeavyCalculation();
dispatcher.dispatch(myListeners, data);
}
The dispatcher is internally using the LinkedBlockingQueue as mentioned above (the Executor uses one internally as well btw), where myListeners is a fixed (concurrent) List of listeners and data the Object to dispatch. On the LinkedBlockingQueue several threads are waiting using the take() method. Now one is woken up as of the new event and does the following:
while (true) {
nextEvent = eventQueue.take();
for (EventTarget target : nextEvent.listeners) {
target.update(nextEvent.data);
}
}
The general idea behind all this, is that for once you utilize all cores for your code, and in addition you keep the amount of objects generated as low as possible (some more optimizations are possible, this is just demo code). Especially you do not need to instantiate new Runnables from scratch for frequent events, which comes with a certain overhead. The drawback is that the code using this kind of GUI model needs to deal with the fact that multi-threading is happening all the time. This is not difficult using the tools Java gives to you, but it is an entire different way of designing your code in the first place.

Updating calculated values in Android layouts using SeekBar

So, I've been working on an app that has a Plan model with a number of different inputs and outputs, and the layout of the app has slider controls for the inputs and labels for the outputs. When an input changes, it updates the model, which then runs a calculation, and then updates the views. I didn't think there was anything wrong with this architecture at first, but even simple calculations seem to run really slowly, blocking the UI thread. Granted, I do have a somewhat complicated way of updating things:
Slider (in a viewgroup subclass) updates its value and sends a message to a delegate (which implements an interface specific to that viewgroup subclass).
Delegate (which holds the model and the control subviews) tells the Plan instance to set a new value, which triggers the plan to recalculate its outputs.
Once the plan finishes its calculations, it sends another message to the delegate, which then tells its output views to update with the new values.
I've modeled this architecture off of an iOS app that I developed which didn't seem to have as big of a problem running the calculations.
Now, I know that Android is significantly different than iOS, so I'm wondering if I'm going about this completely wrong. Is there a way to just tell these views to watch the Plan model for changes and then grab the value it's supposed to display?
Another major issue that I'm seeing here is with the slider input. If I put the model update calculations into a thread, every time the slider changes, a new thread will be created. These threads (as I've seen) will more or less finish in random order, updating the view in such a way as too make very little sense when you should see incremental changes. Is there a good way of threading calculations that are supposed to be changeable with a seekbar?
Have you looked at Observer and Observable?
Maybe your observed model can perform the update using Runnable and then notify the observer.
This is just an idea of the top of my head:
Instead of just starting a new thread for each update from the slider, you could implement some kind of Queue.
You would need a to have a Thread running, that holds the Queue.
public class QueueThread extends Thread {
private boolean running;
private ArrayDeque<Runnable> queue;
private Thread current;
public QueueThread() {
running = true;
queue = new ArrayDeque<Runnable>();
current = new Thread();
}
#Override
public void run() {
while( running ) {
if( !queue.isEmpty() && !current.isAlive() ) { //We only want to start a new thread if there is one or more in the queue AND the old task is not runnning.
current = new Thread( queue.pollFirst() );
current.start();
}
else
try {
Thread.sleep( 200 ); //We need a sleep in order to not hammer the CPU.
}
catch( InterruptedException e ) {
e.printStackTrace();
}
}
}
public void stopThread() {
running = false;
}
public void add( Runnable task ) {
queue.addLast( task ); //Here is where we add a task to the queue. The slider (or whoever posts the updates) must have a reference to this thread object.
}
}
Doing this would allow each update to finish before the next is started. I am not sure how it will do in performance. I haven't tested it or anything. It was just an idea.

Multithreading in a networked swing game: using invokeLater vs locks

I am writing a simple top down space game, and am extending it to allow play over a network with multiple players. I've done a fair bit of reading, but this is the first time I've done this and I'd appreciate some advice on choosing a sensible design.
My GUI is written using Swing. 30 times a second, a timer fires, and repaints my GUI according to data in a gameWorld object in memory (essentially a list of ships & projectiles with positions, etc). Physics updates of the gameWorld are also carried out using this timer. Thus, for the single player implementation, everything happens on the EDT, and this works fine.
Now, I have separate thread dealing with incoming packets from other players. I would like to update the data in my gameWorld object based on what these packets contain. My question is, should I use invokeLater to make these changes, or should I use locks to avoid concurrency problems?
To illustrate what I mean:
runMethodOfInputThread() {
while(takingInput) {
data = receiveAndInterpretIncomingPacket(); // blocks
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gameWorld.updateWithNewGameInfo(data);
}
});
}
}
vs
runMethodOfInputThread() {
while(takingInput) {
data = receiveAndInterpretIncomingPacket(); // blocks
synchronize (gameWorldLock) {
gameWorld.updateWithNewGameInfo(data);
}
}
}
The latter would also require using similar synchronize blocks wherever the EDT accesses the gameWorld, so it seems to me that using invokeLater would be simpler to implement. But am I right in thinking both approaches would work? Are there any other significant pros/cons to bear in mind?
Thanks,
Jeremy
Well, first of all you don not need to choose only one method. You can use locks to make you data structure thread-safe "just to be sure" (since your application is already multithreaded), and use invokeLater to actually apply changes only in EDT -- and in this case JIT likely to optimize you locks down, close to 0.
Next, from my point of view invokeLater is rather preferred way: if you can way around dealing with multi-threaded -- you should use the way, just because multithreading is hard and rich of possible errors.
But applying changes via invokeLater() will put additional pressure on EDT, so, if changes come with high rate you can observe GUI degradation. Also, if gameWorld.updateWithNewGameInfo(data) is havy method taking observable time to complete, it can makes you GUI even freeze. Also, invokeLater puts your task at the tail of event queue, so it'll be done after all events currently in queue. It may -- in some cases -- cause delays in applying changes, which can makes you game less user-friendly. It may, or may not be your case, but you'll should keep it in mind
As for general rule -- not use EDT for any time consuming task. As far, as I understand, network packet parsing is already in seperate thread in your application. Applying changes can (and should) be done in separate thread too, if it is time consuming.
Pros for approach 1:
Minimized complexity
Stability
By restricting access to the 'gameWorld' variable to the EDT thread, locking mechanisms are not required. Concurrent programming is complex and requires the programmer(s) to be vigilant throughout the source base when accessing objects shared amongst threads. It is possible for
a programmer to forget to synchronize in certain instances, leading to compromised game states or program failure.
Pros for approach 2:
Scalability
Performance
Minimizing the processing done on the EDT thread ensures that the games interface and display will remain responsive to the user. Approach 1 may work for now, but later revisions of your game will not be able to scale to a more advanced interface if the EDT thread is busy doing non-ui processing.
Not the second one. You want to have as little as possible running in the EDT. If you are waiting for a lock in the EDT, it's as bad as running all the other code (on the other side of the lock) directly in the EDT since the EDT has to wait for everything else to finish.
Also, it seems that your whole game is running on the EDT. That's bad practice. You should split your code using the model-view-controller pattern. I understand your game is small and can run in the EDT, but you should probably not get into the habit.
You should have your game logic running from a timer thread (java.util.concurrent.ScheduledThreadPoolExecutor) and at the end of every period you "send" your data to the EDT and repaint with invokeLater.
You should also have some separate thread that reads the socket and that thread should write to objects that share locks with the objects you are using in the timer game thread.
My suggestion is as follows
push all loaded data from different users (thread) to a queue
use another thread to read from that queue and update UI from EDT
It should avoid your concurrency issue. How it can be achived
runMethodOfInputThread() {
while(takingInput) {
data = receiveAndInterpretIncomingPacket(); // blocks
blockingQueue.add(data);
}
}
runMethodOfUPdateUIThread() {
while(updatingUI) {
data = blockingQueue.take();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gameWorld.updateWithNewGameInfo(data);
}
});
}
}

Categories