Multi Thread Coding in Android
Learn more about multi-thread coding with multi-core Android devices. For an easy-to-follow example of multi-thread coding in Dalvik, see Multi Core Coding in Dalvik. Visit Native Code to see options available when developing in C/C++ or assembly language.
Introduction and Overview
Where previously multi-core processors sat squarely in the domain of servers and high-performance workstations, they more recently also advanced down into standard desktop PCs and laptops. It was inevitable that they would eventually make it down into mobile devices.
As semiconductor implementation processes keep shrinking, it is no longer possible to simply keep increasing clock frequency, so the simplistic way to keep getting more processing power onto a chip is to add more processing cores.
With Android 3.0 (first release of Honeycomb), Google for the first time officially provided support for multi-core platforms. This was coupled with the arrival on the market of consumer devices based on multi-core ARM processors, like the Motorola Xoom and the Samsung Galaxy S II. Multi core devices have quickly become the norm and part of every-day reality for the Android ecosystem. This review will seek to give an overview of how to take advantage of the multi core environment.
What did multi-core processors ever do for us?
The free lunch
The lunch you have to pay for
So, whereas you do get some benefits for free, if you actually want to ensure maximum possible performance (or responsiveness) for your application, you probably need to adapt it. Or simply design it differently from the start—usually, retrofitting concurrency onto an existing program is a tricky error-prone process.
The way to benefit is to design your system to take advantage of concurrency, by doing more than one thing at once. Within a single app, this means splitting execution up into multiple threads performing different tasks, or separate portions of a larger single task, simultaneously on separate cores.
The following will show off some ways available to you as a software developer to make use of concurrency to speed up your apps.
The lunch you didn't want
Going back to the very first versions of Android, multi-threading has been supported, but because multi-core devices have not been supported, not many apps have been exposed to true concurrency. There are many problems that can only occur, or occur much more frequently, when you have applications where threads are executing concurrently on different cores and interacting in strange ways. Therefore, incorrectly written multi-threaded software that has worked perfectly fine before might start showing incorrect behavior on multi-core devices. Google have taken a few steps to try to reduce this risk, described more in the next section.
The lunch for the operating system
A common misconception about multi-core systems is that they consume more power than single-core systems. It is certainly the case that two cores executing at peak frequency and peak voltage will (ignoring thermal effects) consume twice as much power as one core doing the same. However, having multiple cores gives the power management subsystem more flexibility which it can use to achieve a better system-level energy consumption. For example, you can execute two tasks in parallel at a lower frequency (and voltage), completing in the same time but consuming less energy than running on a single core at a higher frequency.
And if you want to run parallel <SETI|Folding> at Home on your dual-core mobile device, I'm sure you will find having to leave it permanently plugged in a small cost for achieveing double the package throughput ;).
Android support for multi-threading
For the purpose of this review, the Android environment consists of two fundamentally separate environments for multi-threaded software development: Dalvik applications and native code.
Multi-threading support in Dalvik
Many Android apps will be developed for the Dalvik runtime environment. This means that first of all, normal Java threading and synchronization support is available to you. However, there are also some Android specific extensions that you could (and should) make use of. The next section will be dedicated to this topic. Dalvik applications are developed using the Android SDK, usually in the GUI environment provided by the Android Development Tools (ADT) plugin for Eclipse.
Multi-threading support in the NDK
When you want to build parts of, or all of, your application in C, C++ or assembly, you need to use the Native Development Kit (NDK). Originally, this was supported only as a hybrid solution where the UI is still handled in Dalvik, but you can make JNI calls out into shared libraries built from C/C++ code. However, Android Gingerbread (2.3) introduced the concept of a Native Activity, which lets you implement your entire app as shared libraries, invoked automatically by the environment.
Regardless of which of these two you are doing, your basic multi-threading support comes in the form of the Pthreads API implemented in the Bionic C library. This implementation is mostly compatible with the (e)glibc one used in standard Linux. Using the NDK for multi-threading will be discussed after Dalvik.
Multi-core support in system libraries or services
If you are building libraries or services to be included as part of a customized build of the entire Android OS, you just use the toolchain supplied with the Android OpenSource distribution. Your basic multi-threading support is still available as the Pthreads API provided by Bionic, just like for the NDK. However, this review is focused on app development, so will not go into more details on this subject.