I'm trying to develop a game. It's a simple whack-a-mole type of game where something pops-up the screen and you click on it to kill it. I was thinking of giving the "moles" their own thread so that they can do their own animation, event handling, etc. in their own lifecycle until eventually killing themselves.
Will this kind of "each object has its own thread" implementation be good for an Android game?
Definitely not. Do not give each mole its own thread. This would be too much use of threads while it is needless to say that in this type of game you do not need such a number of threads. Just keep everything in the main thread and use some listeners to kill moles. (=make invisible)
Yes, it is a performance issue and a matter of developer's decision. Why should you create a thread for each mole? This is the right question because doing so is a far more unrealistic decision. Will each mole access a database? communicate with a server? I don't think so.
Anyway, since it is a mole on the screen, you will only need one instance of it that you can render/move it around/disable/etc in the main thread.
This could work, if there aren't a ton of objects, and a ton of activity for each object.
I would suggest thread pooling. Pull out inactive objects out of threads and put in active threads.
Stay single threaded until you actual need to change - especially for a simple game, you won't have the kinds of performance problems that need threading.
At any rate the general approach is not to thread out individual entities, but entire steps of algorithms performed across 100s or 1000s, or even entire systems (e.g. audio, physics etc.) - and perhaps the most extreme but common case is to split your rendering submission into its own thread for all rendering, with animation, physics, gameplay logic etc on another thread, in exchange for single frame latency on everything.
Not to mention that the overhead of having very many threads often becomes limiting - if you have 2 or 3 moles it might be fine, but if you have many more you will quickly reach the point of diminishing returns - not to mention the difficulties inherent in keeping many threads in sync and avoiding deadlocks, race conditions etc.
Related
AFAIK, android uses Single thread architecture, where all UI components event are dispatched,i.e. main thread or UI thread.
But why we cannot perform UI operations on separate thread other than main thread?
The main problem is related to the context. In a background thread you could update some UI stuff which is not in the current context. This is one of the reason.
UPDATE:
From the Android developer guide:
Additionally, the Andoid UI toolkit is not thread-safe. So, you must
not manipulate your UI from a worker thread—you must do all
manipulation to your user interface from the UI thread. Thus, there
are simply two rules to Android's single thread model:
Do not block the UI thread
Do not access the Android UI toolkit from outside the UI thread
You can read more on thread safety from [1] [2] and you can read even [3] with a small exmaple and explenation!
Hope that now it is more clear sorry for the short and quick answer before :)
Well, first of all I need to state that this is a design level problem that has been discussed by many generations of programmers :)
Now technical details:
A GUI framework is a very complex thing. A GUI framework needs to display (draw) certain views (or windows) and route external (mostly user) inputs to the view that the input is targeted to. Now, to manage the screen with views with proper event dispatch to each view, all views shall be part of a graph and the simplest form of such a graph is a tree. So, you essentially have a tree of views to manage - where information should be fed to a root view from where your whole event routing takes place to child views.
Naturally, one dedicated thread to do manage this view hierarchy and event routing by monitoring a message queue to which all these drawing and input events are posted - by itself or any other threads - is a neat and simple solution. Any other solution that involves more than a thread will make the already complex view management and event routing code prone to dead/live locks.
Along with these technical details, you need to keep it in mind that you are trying to do business with a framework which is going to be used by other people who usually don't have faintest idea about the inner details of your architecture. Introduce threading support in such a framework is an open invitation for synchronization bugs (read: deadlocks, grumpy end users who are programmers AND ultimately bad business).
Android (and 99% other GUI toolkits) adopts this method. Simply because it makes things simpler and less error prone to have one main thread to deal with all error prone processing. All other threads are free to request it to do things by posting messages to the main thread's message queue. It is a balance between complexity and stability.
The only drawback of this approach is smooth updates of views - if you have many views to update simultaneously, OR your view hierarchy itself is really nested and complex. This drawback of this single threaded architecture manifest itself in pretty obvious forms in Android like:
Animating multiple views simultaneously is never smooth - unlike iOS where they have taken the pains to move certain parts of this operation to more than one threads of execution.
Android documentation need to remind the programmer all the time not to do lengthy operations in main thread AND to avoid deeply nested view hierarchies.
As we know, when we update the UI from the non-ui-thread, we use Handler or AsyncTask. We can find a lot of articles on how to use these methods on the Internet. But I cannot find an explanation on why a UI element cannot be operated from the non-ui thread? Can anyone help me?
I believe this decision was made by the Android team (and many other UI frameworks for that matter) because of the following reasons
Synchronization
Security
Performance
Synchronization
The simplest reason for following a single threaded model for UI is that it is the easiest way to ensure that the User Interface is not being updated by multiple sources at once and therefore, corrupted. If you imagine that multiple threads can modify the UI, it would take each thread its own amount of time to execute a portion of its code, and with the different execution speeds generate a bad user experience.
Security
Ensuring that one thread can access the UI is also a security measure, preventing any slave threads that accidentally (or purposefully) try to corrupt the UI from doing so, simply by not allowing it.
Performance
The core fact of the matter here is that UI operations, and re-rendering and re-drawing visual layers and elements is an expensive process. It can affect the performance of the framework and cause leaks or lags with the deadlocks and synchronisation in-between. So I believe this was done for the sake of performance too :)
I suspect it's because a UI is a state machine, having multiple threads operate on a single state machine makes it difficult or impossible to reason about the current state of the UI and what transitions are available at any given time. There would be unpredictable results, so it's best to keep it separated from code executing in an AsyncTask.
Is there any downside to making every one of your methods synchronized in Android?
Yes - it will end up taking out locks when you don't really want them. It won't give you thread safety for free - it'll just slow down your code and make it more likely that you'll run into deadlocks due to taking out too many locks.
You need to think about thread safety and synchronization explicitly. I usually make most classes not thread-safe, and try to limit the number of places where I think about threading.
The "make everything synchronized" approach is a common one in what I think of as the four stages of threading awareness for developers:
Complete ignorance: no synchronization, no awareness of the potential problems
Some awareness, but a belief that universal synchronization cures all ills
The painful stage of knowing where there are problems, and taking a lot of care over getting things right
The mythical stage of getting everything right naturally
Most experienced developers are in stage 3 as far as I can tell - with different levels of ease within it, of course. Using immutability, higher-level abstractions instead of the low-level primitives etc helps a lot - but ultimately you're likely to have to think a fair amount whenever you've got multiple threads which need to share state.
For example, Java Swing and Android UI both use a single threaded model where a single UI thread is responsible for updating all the UI. What made the framework designers chose one thread model over the other?
Wouldn't multiple threaded UI model potentially give you more performance albeit at the cost of more complexity? I realize that the latter is a big deal because thread related bugs are nasty but I am wondering if there are any other advantages to single-threaded model other than simplicity?
What made the framework designers chose one thread model over the other?
From the horse's mouth:
AWT was initially exposed as a normal
multi-threaded Java library. But as
the Java team looked at the experience
with AWT and with the deadlocks and
races that people had encountered, we
began to realize that we were making a
promise we couldn't keep.
This analysis culminated in one of the
design reviews for Swing in 1997, when
we reviewed the state of play in AWT,
and the overall industry experience,
and we accepted the Swing team's
recommendation that Swing should
support only very limited
multi-threading.
(Read the whole article, it explains the decision in great detail and states that the exact same problems and eventual move to a single-threaded model had even occured earlier at Xerox PARC - the place where almost everything we consider bleeding edge modern in CS was invented 30 years ago)
Wouldn't multiple threaded UI model
potentially give you more performance
albeit at the cost of more complexity?
Absolutely not, because drawing the GUI and processing user actions (which is everything the UI thread needs to do) is not going to be the bottleneck in any sane 2D application.
Wouldn't multiple threaded UI model potentially give you more performance albeit at the cost of more complexity?
Not in most cases, and that added complexity would do more harm than good the vast majority of the time. You also have to realize that the UI framework must deal with the underlying OS model as well. Sure, it could work around the model and abstract that away from the programmer, but it's simply not worth it in this case.
The amount of bugs caused by multiple threads updating the UI ad hoc would far outweigh what would be for the most part meaningless performance gains (if there were even gains, threading comes with an associated overhead of its own due to locking and synchronization, you may actually just be making the performance worse a lot of the time).
In this case it's better to use multiple threads explicitly and only when needed. Most of the time in a UI you want everything on one thread and you don't gain much if anything by using multiple threads. UI interactions are almost never a bottleneck.
No, probably not. At least not when you try to run the threads on the CPU. On the GPU there is already a lot of parallel processing in various forms. Not as much for the simple GUI work, but for fancy 3D (shading, reflections etc.)
I think it's all about deadlock prevention.
Swing's components are not considered thread-safe, and they don't have to be because of this Event Dispatcher Thread. If the UI was multi-threaded, the whole app would have to rely on every component behaving itself in a thread-safe manner, and if any didn't, then deadlocks could arise in obscure situations.
So, it's just safer.
Not only that, but the same design has been chosen by Windows Forms (& .Net), GTK, Motif, and various others. I wonder if Java would have been forced into this decision by the underlying OS APIs which they interact with. Certainly SWT is forced into this situation by Windows Forms.
For more info, "EDT" is a good place to start http://en.wikipedia.org/wiki/Event_dispatching_thread
For .NET, the equivalent of SwingWorker is known as BackgroundWorker.
They are all not single threaded anymore. The modern ones all build a scene graph now and render/compose them in different threads. A Html widget does layout calculations not only in multiple threads but multiple processes.
In general with the widespread use of MVVM pattern it makes no sense for complex models. You can update the Models from any thread. IMHO this was the major reason for it's invention not the data binding argument.
You can debate philosophically if you call this still single threaded just because the mouse/key/touch events arrive all in one thread. Manipulations happen in many places nowadays. And the GPU scene graph is rendered with thousands of parallel shaders how does this apply to the question?
This is because of the nature of an UI application.
You should read the input (Mouse or Keyboard), dispatch the events, let them process and than draw the screen again.
Try do it on multi-thread process.
I am currently developing an Android game that is similar to a classic arcade space shooter. Thus far I have almost everything finished, but my code is not quite to my liking and I am trying to find out how to improve it.
The problem I am having is with enemies and other objects entering the screen.
Currently I am using a Runnable object that I pass to a thread, and in this Runnable is an array of all of the distances that will trigger new enemies to come in from the top or sides of the screen. In the run() method, I check the time and if the System.uptimeMillis() is greater than or equal to an element in my array, I fire another method that uses a switch statement to determine the event to run.
This is all becoming quite a hassle to manage and that is why I was wondering if anybody know of a more efficient and neater way to manager the queued enemies.
Also, my array I create is of 200-some objects and once they are off the screen I was nulling them. Obviously this was firing of the GC too often for a well-performing game. Is it best just to reuse enemies that are destroyed or go off screen? Or is there a better way for this as well? (I am just ensuring that my program is the best it can be before it ventures into the wilds of the Market)
Thank you in advance,
-Roflha
I suggest you look at this code for reference. It has a good way of dealing with objects, collisions and stuff.
And its written by a google employee which always sounds cool for some reason.