I am working on making a game with libGDX and I really want to thread the game so I am running a paint loop and a logic loop on separate threads much like you would making a simple java swing game with the paintcomponent loop and the runnable run loop.
I am experienced with threading in c but not so much in java.
The only way I was able to make a thread was by making a class that extends threads and then creating the run loop in there.
But the point of making the run loop was to allow each screen to compute logic freely, so I would end up needing some sort of abstractscreen class that has the custom thread class implemented.
I am asking if there is a simpler or more standard way of implementing threads for this situation.
The libGDX library already runs a separate render thread for the OpenGL context updates. See http://code.google.com/p/libgdx/wiki/TheArchitecture#The_Graphics_Module
We already learned that the UI thread is not executed continuously but only scheduled to run by the operating system if an event needs to be dispatched (roughly :p). That's why we instantiate a second thread we usually refer to as the rendering thread. This thread is created by the Graphics module that itself gets instantiated by the Application at startup.
The ApplicationListener.render() method on your main game object will be invoked by this render thread once for every screen refresh (so it should be about 60hz), so just put the body of your render loop in your implementation of this method.
You can create an additional background thread (e.g., for game logic) in the create method of your ApplicationListener (be sure to clean it up in the dispose method). Other than the render thread, I don't think any of the pre-existing threads would be the right place for game logic.
For communication between the threads, you can use any of the existing Java synchronization approaches. I've used Java's ArrayBlockingQueue<> to send requests to a background thread. And I've used Gdx.app.postRunnable() to get my background threads to push data to the render thread (such Runnables are run on the next frame, before render() is invoked).
Not sure what you mean, but it is standard that the drawing on the screen (reflect changes to the display) is done by a dedicated, single thread (e.g. see Swing framework). This is because it is quite difficult to let multiple threads draw on the screen without messing things up -- only few implementations do this. Hence, if you are planning to implement the GUI framework yourself, single threaded drawing approach would be recommendable.
As for your business logic, it depends on many things. A very simple approach could indeed to spawn a new thread for each activity. These threads can then post the result to the said GUI thread. The problem with this approach is that your efficiency can drop significantly if many activities are concurrently executed at the same time, because in Java, every thread maps to a native OS thread. You can use thread pools to avoid that. Java standard library provides thread pools as ThreadPoolExecutor or if you want a bit higher abstraction, ExecutorService.
Related
I'm building a game from the ground up in Java, using only standard libraries. So far I've got a game that prints ASCII characters in a swing window to represent 3d objects. It's pretty cool. Anyway, since I don't know about threading or scheduling, I'm wondering if I'm using some bad practices that could cause issues later on. I have one repeating task running to update the level every tenth of a second, but whenever I want to delay something, I use
Executors.newScheduledThreadPool(1).schedule... etc etc.
Is it good to make a "new scheduled thread pool" every time I want a new delayed task to run once, or should I try to keep one instance going? If it's good to reuse instances, when is it appropriate to make a new one?
Concurrency in Swing applications is tricky: everything that impacts the GUI needs to be executed on a single thread (called the event-dispatch thread). So when you set up a separate thread to perform some long-running background task (e.g. generating a map for an area the player isn't viewing yet) then you need to work carefully to synchronise with anything that might impact the GUI.
In general you have two options for the simpler use cases:
If it's a short activity that immediately impacts the GUI then use a Timer to trigger an event on the event-dispatch thread. See here.
If it's a long activity then use a SwingWorker. See here.
There are plenty of other ways to achieve interaction with other threads (e.g. see SwingUtilities.invokeLater and SwingUtilities.invokeAndWait) but given you have said you are just starting out I would suggest sticking to one of those two for now. They take care of most of the complexity for you and let you focus on your game logic.
The context in this case is creating a game loop that integrates with the model and updates the view once per frame. Listeners interface with the controller, controller updates the model, repaint() handles the view update from model (on an overridden paintComponent() on a JPanel).
Appropriate answers include "never", haha.
This is a question I would think there is a preferable answer to, so it shouldn't be in violation of the rules.
I'm asking this because the main game loop is a Runnable instance which I'm locking to 60FPS (roughly, at the moment. Few milliseconds of difference as the current render loop is very inexpensive and 1000 / 60 loses a millisecond or two each cycle). Not locking the frame rate via Thread.sleep() causes something like 2.3 billion frames per second (apparently), which understandably thrashes my CPU. Not a problem per say, more of an example why frame-locking is desirable.
However in every single answer I come across, every single comment, the majority of them say "why are you even touching Thread.sleep() you don't want the EDT to sleep". Which is understandable if you have flaws in your loop that cause non-responsiveness, but this isn't the case in the applications I've put together yet. I've read all of the associated Event Dispatch Thread documentation, how to use Swing Timers, etc. I've even used Timers myself, and SwingWorkers too (in one case to delegate icon loading to the background to prevent blockers on GUI instantiation).
Is there even a preferred method here? I haven't come across many / any standalone game solutions in Java that don't rely on libgdx.
Use Swing Timer when:
You don't want to throttle or control the time between updates. Swing Timer only guarantees "at least" duration (it will trigger AFTER a given delay) and the length of time in which the event is processed may effect the amount of time before the next update.
So, if you have a delay of 16ms (rough 60fps), your callback takes 20ms to process, the time between the first and second callback may actually be 36ms
You would also use a Swing Timer when you want to use the existing (passive) rendering system supplied by Swing
Swing Timer is relatively simple and easy to use, it triggers callbacks within the Event Dispatching Thread, making it easy to modify the state of the game and schedule an updates to the UI, this reduces possible thread race conditions (between the painting and the updating)
Use Thread#sleep when:
You want more control over the timing, producing variable delays. In order to do this, you will need to manage your own Thread
This approach is more suitable to more complex animations and when you are using a BufferStrategy to control the output.
The reason for this is, with a Thread approach, you run the risk of race conditions between your thread changing the state and the paint cycle painting it. Instead, you will need to take control of the paint process yourself, so you know that when you paint something, the state does not change while you do it.
Using this approach provides more flexibility and control to make decisions about when things get done (and how), but increases the complexity and your responsibility for doing things
Thread.sleep is almost certainly used in the implementation of javax.swing.Timer and java.util.Timer, but these days the only real use case of Thread.sleep is for creating a timeout on something, typically an I/O connection. I used this once at work way back for delaying updating the GUI after requesting the users messages until a certain amount of time past from the last message sent from the server. I also used it here
In your case, you should be using the swing timer for your game loop
I have hundreds of different functions that run in the EDT. A great deal of them include long-running tasks and some include changes to the GUI. Occasionally the GUI hangs for users but it is hard to keep track of all the locations this happens due to the GUI hangs not happening in the same areas 100% of the time. The issue is not high priority because the hang usually starts working after a minimize/maximize of the window, but it needs to be done eventually.
After some research I discovered I could use doInBackground() under SwingWorker for any methods with labor-intesive work and use done() for GUI drawing. Also I believe I can use SwingUtilities.invokeLater for every GUI drawing that happens to be in the doInBackground() function. However, I want to avoid adjusting every one of the hundreds of functions in my code.
Is there a way I can use a single SwingWorker and send any long-running methods to the doInBackground() function? Using the invokeLater function multiple times for every misplaced GUI code where a SwingWorker would be used is not a problem as it is not that frequent.
If this is not possible is there some kind of alternative I can use? Thank you.
All methods that update the GUI must be invoked on the EDT, otherwise you may end up with some unexplained GUI behavior (which sounds like what you are seeing). You could have repaints that don't happen properly, thread races, etc.
It is not advised to run long running tasks on the GUI because they will cause the GUI to become unresponsive, so for long running tasks, SwingWorker is a good solution to use (note that the process and done methods are called on the EDT automatically so your worker can do its long running work in doInBackground but you can safely update the GUI without using SwingUtilities.invokeLater from the done method).
As you mentioned you have hundreds of methods and you don't want to call SwingUtilities.invokeLater every time, you might want to look into one of the task frameworks. The Swing Application Framework was developer under JSR-296 http://java.sun.com/developer/technicalArticles/javase/swingappfr/ but is not actively supported, but still provides a nice framework.
http://en.wikipedia.org/wiki/Swing_Application_Framework is a list of alternative frameworks.
It sounds like you are going to need to do some significant rewriting in your application. Calling GUI methods from outside the EDT is unsafe to do.
I don't see how what your asking would be possible. Swing has no way of knowing of what would qualify as a "long running" method call before execution. If the method is already being executed (on the EDT) Swing can't simply pick it up and move it to a new thread. Even if you would indicate which method calls should be run in background threads pulling it off would be hard. The only way I can think of to make this possible in Java is with AOP (you could intercept the method calls). But implementing AOP would be harder then reimplementing your existing application to use SwingWorkers.
It sounds like the architecture of your Swing application is broken. Long running tasks must not be executed on the EDT. I'm sorry but I think you just have to bite the bullet on this one. If you want your application to feel snappy, responsive and have predictable behavior you will have to fix this by putting the long running code in background threads.
If your application uses a lot of background tasks you might want to use the excellent Swing Task API. Otherwise you will find yourself in a SwingWorker spaghetti quite fast.
for every GUI drawing that happens to be in the doInBackground()
You can't call Swing drawing, updating, etc. methods in the 'doInBackground()' method (well actually you can, but you must not do that). This is because this is the method which gets executed off the EDT. GUI drawing and component updates must only be called in the 'done()' method of a SwingWorker.
I'm quite a beginner at Android so here is the thing:
I have multiple threads in my game: the main activity, the renderer and the game loop.
So the question is:
Should I derive classes from Handler class and send messages to threads or should I use synchronized functions for thread-to-thread communication?
What are the pros and cons of these two approaches?
(I'm also not an expert in Java, C++ is my homeland)
Handlers are good when you need to bring the action back to the activity you're running.
When it comes to communication from the UI to other threads in my apps, I prefer to use threadsafe collecitons to manage the communication from one to another. For example, when I am developing a game, I will commonly have the UI thread report touch events to my game thread by inserting them into a LinkedBlockingQueue, which the game thread empties at its leisure.
The Handler was designed to simplify threading. You should use it where ever possible BUT you can only use Handlers on threads managed by a GUI event scheduler. For most games, the main UI and the OpenGL threads are managed by event schedulers and Handlers work just fine on them.
The two proposed options differ fundamentally. With Handlers you are posting a message for the thread that owns the handler. That is, you would post a message to the UI thread for it to modify the UI in some way. With synchronized methods, the thread that's sending the message will be the one doing the executing. The concurrency abstractions in Android are pretty good so I would urge you to use them whenever possible rather than rolling your own.
In the past few years I've mostly done UI development in Eclipse, which is very conservative in terms of thread access: any attempt to change a property on a UI widget (e.g., color, text) from outside the UI thread throws an exception.
I am now looking at an existing program in Swing that has a window with a large number of custom widget. There is a separate threads that runs a mutation function for each of these widgets, and the mutation function reads the value of some things (e.g., label colors and values) and writes some (e.g., changes background colors). Note that there is no custom painting involved or anything like that, just a bunch of changes to the sub widgets it contains which are mostly JLabels.
At present, this runs from the separate thread, not from the Swing event thread. This thread goes over all the 400 widgets and calls the mutator on each. The updates seem to work correctly, but the GUI is unresponsive to user input.
If I take the whole thing, which runs for about 0.4 msec from outside the Swing thread and wrap every call to a mutator in an invokeLater or invokeAndWait, the UI is a lot more responsive.
What I'm trying to understand is:
1) Is it sometimes legitimate to make all these calls from outside the Swing thread?
2) What is the impact on the Swing thread and why is the UI less responsive when I call it from outside?
From "Nothing" to intermittent problems to "Everything Broke, pull everyone off to work on the GUI!"
The main (most obvious) visual effect is that if you hold up the GUI thread (like someone presses a button and you do a sleep(5000) or something), your GUI won't repaint. It can't because you are holding onto the only thread it's allowed to pass you! This makes people think Java is really slow. It's not bad, but it's easy enough to program that a lot of people who don't bother researching practices like this have produced shipping products.
The next biggest problem is that when you are drawing the screen in another thread (like the one passed to main), it can have strange behavior. Swing is already too picky about how you render your frames--take out threading as a variable!
Finally, rarely (or often if you are calling a swing component in a tight loop on the wrong thread) you can get thread collisions. If that happens an exception may be thrown (or not) and something will probably render wrong, but it may not be obvious.
1) Is it sometimes legitimate to make all these calls from outside the Swing thread?
There are a few exceptions (setting the text value of a text field, for example, does automatic EDT proxying for you) - but there are no situations where it is better to do so. If you are performing lots of updates, you can do them all in a single EDT call (a single call to invokeLater()) instead of individual calls - but even that sort of batching very rarely helps things. Long and short: Perform operations on Swing components from the EDT. That includes reads and writes.
2) What is the impact on the Swing thread and why is the UI less responsive when I call it from outside?
Well, the EDT is responsible for updating the GUI. If you call from outside, it isn't 'less responsive' - it's that the actual low level system calls that update the user interface don't occur (at all). What is probably happening in your app is that the original developers are getting lucky and changing state in the swing component without creating a really nasty race condition. Then some other event is causing a repaint to occur on the EDT, which results in the component being updated. This may appear to be a 'lack of responsiveness' - but what's really happening is a 'lack of screen refresh'.
The EDT is just a regular thread, but it is a bit special in that it runs in a tight loop that processes GUI related signals (draw commands, for example). The semantecs of posting these types of commands on the EDT is really, really different from what we typically think of as Java threading (it involves submitting operations to a message pump).
Long and short - all those Javadocs that say 'only interact with Swing objects on the EDT' are written for a reason. Don't mess with it. If you want to do background processing, fine - but you are responsible for proxying the interaction with the J* components back onto the EDT (most generally using invokeLater() ).
There really are no exceptions. Kevin is partially correct - the JTextComponent.setText() is advertised as thread safe. However, looking at the 1.6 code, it provides synchronization on the document object and does not use the EDT. This is fine, unless another swing component (or something that controls swing components) is listening to the document object. Save yourself the trouble of worrying about it, and just always use the EDT - like Kevin says, there really are no situations (that I'm aware of) to do otherwise.
Hard to say without digging into the code; the behavior is undefined. If your background tasks were long running (> a few seconds), you'd see the opposite effect - using the EDT will make the UI unresponsive while your tasks are running.
Fortunately, it sounds like doing it the right way is working best for you anyway. :)
Sun used to say it was ok to use other threads with components that haven't been realized, but later recanted:
Related stackoverflow question
Check out Sun's UI tutorial on swing and concurrency (I'd post the link, but this is my first answer on stackoverflow0.
The basic problem is that non-thread-safe objects are executed in a multithreaded fashion. Even something as simple as reading a HashMap can be caught in an infinite loop. Because AWT uses locks (badly), you can also end up with deadlocks. However, you are likely to get away with it, although you might find that an updated version of Java suddenly causes you issues on some customer machines.
(BTW: It's AWT's Event Dispatch Thread, not Swing's.)
For (1) as a rule of thumb anything that updates pixels on screen must be called from the Event Dispatching Thread (EDT). Where some JVMs may handle updates from outside the EDT acceptably you should never rely on this working, some machines and different look and feels will not work acceptably. The behaviour is undefined - and this could explain the lack of responsiveness you have seen.