Synchronization between worker threads of an ExecutorService - android

Does the fact that an ExecutorService stores tasks in a blocking queue create a happens-before relationship between the completion of one task and the subsequent start of another task?
My reason for asking is that I've been tasked with writing a Cordova plugin for Android. Cordova plugins have a method called execute(...) that is overridden to perform different actions. Apparently, the plugin is instantiated once, and then execute(...) is called repeatedly in a worker thread of an ExecutorService. If my understanding of how Cordova plugins work is correct, then I wonder if I have to synchronize execute(...)'s access to the plugin state.
Edit: My understanding of how Cordova plugins work was incorrect, so my reason for asking this question has been invalidated. But I'll leave it up out of curiosity. (Cordova plugins are constructed, and execute(...) is called, in a thread named JavaBridge... apparently always the same thread, though this is not documented.)

No, the tasks being stored in a BlockingQueue does not guarantee thread safe execution of the worker threads. The ExecutorService interface and it's implementation provide a framework that abstracts the creation of individual threads. The number of worker threads spawned by the executor depends on the pool size configured.
Once a worker thread is spawned, it goes about doing it's work normally. If it gains access and tries to modify an object that is currently being modified by another worker thread, then undefined behavior will happen. It is left up to you to ensure that the modification happens in a synchronized manner. An example of this can be found in the PhotoManager.java class in the sample app available at http://developer.android.com/training/multiple-threads/index.html (intended as a multi threading example for Android developers).
The BlockingQueue is a queue that holds the tasks. The term 'Blocking' refers to the manner in which elements are inserted and removed from the queue. As such, it does not provide any guarantees about the actions taken by the tasks that it holds.

Related

asynctask doInBackgound() not running if there's a asynctask already running

When the user logs in into my app. I am starting an asynctask to maintain the user session. And that async task is running indefinitely till the user logs out. My problem is that when I try to start other asynctasks, their doInBackground() method is never executed.
I read somewhere that if an async task is already running, we cannot start new async task. I can confirm this because when i removed the user session async task, it worked properly. Is there a workaround?
P.S.: I have already used executeOnExecutor() method. but it didn't help.
For potentially long running operations I suggest you to use Service rather than asynctask.
Start the service when the user logs in
Intent i= new Intent(context, YourService.class);
i.putExtra("KEY1", "Value to be used by the service");
context.startService(i);
And stop the service when the user logs out
stopService(new Intent(this,YourService.class));
To get to know more about Service you can refer this
Service : Android developers
Service : Vogella
To know more about asynctask vs service you can refer this
Android: AsyncTask vs Service
When to use a Service or AsyncTask or Handler?
I read somewhere that if an async task is already running, we cannot start new async task.
Yes,That is fact that you can't run more then 5 (five) AsyncTaskat same time below the API 11 but for more yes you can using executeOnExecutor.
AsyncTask uses a thread pool pattern for running the stuff from doInBackground(). The issue is initially (in early Android OS versions) the pool size was just 1, meaning no parallel computations for a bunch of AsyncTasks. But later they fixed that and now the size is 5, so at most 5 AsyncTasks can run simultaneously.
I have figure out Some Threading rules and i found one major rule is below ,
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
What is definition of AsyncTask?
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
How & Where use it?
AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended to use it.
Why you can't use multiple AsyncTask at same time ?
There are a few threading rules that must be followed for this class to work properly:
The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
Running multiple AsyncTasks at the same time — not possible?
Test sample of parallel excution of AsyncTasks
Try Executor
You should go with Executor that will mange your multiple thread parallel.
Executor executor = anExecutor;
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());
...
Sample Example 1
Sample Example 2
Just like a few others here, I object to the premise of the question.
Your core problem is that you are using an AsyncTask to perform a task beyond its scope. Others have noted this too. Those who offer solutions that can mitigate your problem through low-level threads (even java.util.Concurrent is low-level which is why Scala uses Akka actors as an abstraction), Service, etc. are quite clever, but they are treating the symptom rather than curing the disease.
As for what you should be doing, you are not the first to want to maintain a user session in an Android application. This is a solved problem. The common thread (no pun intended) in these solutions is the use of SharedPreferences. Here is a straightforward example of doing this. This Stack Overflow user combines SharedPreferences with OAuth to do something more sophisticated.
It is common in software development to solve problems by preventing them from happening in the first place. I think you can solve the problem of running simultaneous AsyncTasks by not running simultaneous AsyncTasks. User session management is simply not what an AsyncTask is for.
If you are developing for API 11 or higher, you can use AsyncTask.executeOnExecutor() allowing for multiple AsyncTasks to be run at once.
http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor(java.util.concurrent.Executor, Params...)
I'll share with you, what we do on our App.
To keep user Session (We use OAuth with access/refresh tokens), we create a Singleton in our Application extended class. Why we declare this Singleton inside the MainApplication class? (Thats the name of our class), because your Singleton's life will be tided to the Activity that has created it, so if your Application is running on low memory and Garbage Collector collects your paused Activities, it will release your Singleton instance because it's associated to that Activity.
Creating it inside your Application class will let it live inside your RAM as long as the user keeps using your app.
Then, to persists that session cross application uses, we save the credentials inside SharedPreferences encrypting the fields.
yes starting 2 or more asynctasks simultaneously may cause issues on some devices. i had experienced this issue few months back. i could not predict when the 2nd asyncTask would fail to run. The issue was intermittent may caused by usage of memory as i was executing ndk code in asynctask. but i remember well that it depended on memory of device.
Similar question had been asked before. I would post the link for the similar question.
AsyncTask.executeOnExecutor() before API Level 11
Some users suggest go for Service. My advice is don't go for that path yet. Using service is much more complicated. Even you are using service, you still have to deal with threading, as
Note that services, like other application objects, run in the main
thread of their hosting process. This means that, if your service is
going to do any CPU intensive (such as MP3 playback) or blocking (such
as networking) operations, it should spawn its own thread in which to
do that work....
If we can solve a problem in elegant way, don't go for the complicated way.
I would suggest that, try one of the APIs in java.util.concurrent as suggested in below
AsyncTask is designed to be a helper class around Thread and Handler
and does not constitute a generic threading framework. AsyncTasks
should ideally be used for short operations (a few seconds at the
most.) If you need to keep threads running for long periods of time,
it is highly recommended you use the various APIs provided by the
java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and
FutureTask.
I can't give you any code example so far, as I do not know how you design your session managing mechanism.
If you think your long running session managing task shouldn't bind to the life cycle of your main application life cycle, then only you might want to consider Service. However, bear in mind that, communication among your main application and Service is much more cumbersome and complicated.
For more details, please refer to http://developer.android.com/guide/components/services.html, under section Should you use a service or a thread?

libDispatch serving main queue without dispatch_main on Android

I am using libDispatch (GCD) opensource on Android platform.
So, most of the complex time consuming tasks are being done through NDK (where i am using libDispatch).
For some calls, I am using dispatch_async(get_main_queue)...This is where the problem is coming...
I am able to run tasks in the concurrent queues but not on main queue.
Since this requires dispatch_main() to be called which we cannot do on here as Java thread will be blocked in that case.
So, is it possible to run the Java UI on some secondary thread and hook the dispatch_main() to serve the dispatch_main_queue here?
OR : Do I need to keep serving the main_queue from JAva main UI thread through JNI ?
Look into _dispatch_main_queue_callback_4CF which is the function you can call to drain the main queue. It will return like a normal sensible function after executing the queued operations, instead of killing the thread like dispatch_main.
Note that you'll need to call _dispatch_main_queue_callback_4CF on a regular basis from your Java UI thread, possibly each iteration. The official Cocoa implementation uses _dispatch_queue_wakeup_main() which uses mach messages to kick the main thread out of any sleep states so it can guarantee the callback function is called quickly, but you'd have to do some work to enable that and build your own libDispatch port. In reality on Android I don't think the main UI thread is ever put to sleep while your app is active so it shouldn't be an issue.
There is a ticket open on the libDispatch site at https://libdispatch.macosforge.org/trac/ticket/38 to make _dispatch_main_queue_callback_4CF a public function. The ticket is marked "Accepted" but no word on if/when that will happen.

Understanding when and why to use different Android threads

Hopefully someone can explain this to me or point me to a resource I can read to learn more. I am building an app that uses a ListView and a custom list adapter that I modeled off one of the many tutorials available online such as this one:
http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/
It worked fine. However, every example of how to do this runs the process of building the list of objects to be displayed and collecting the required data on separate threads.
I want to know why/couldn't you just put everything into onCreate? I can't see a reason why you would need separate threads to make this happen. Is there some general form/standard for when/what must me run on certain threads?
The Android docs on this are very good, as with most things.
The upshot is: the UI should always be responsive. So if you have some operation that will take enough time that the user will notice, you might want to consider not running it in the UI thread. Some common examples are network IO and database accesses. It's something of a case-by-case basis though, so you have to make the call for yourself a bit.
Well, if building the list of objects is not a relatively short process, doing it in onCreate() would be blocking/slowing the main thread. If you use a separate thread, it will allow the android os to load all of the UI elements while you are waiting for the list to be populated. Then when the list of objects is ready, you can instantly populate the already initialized UI, as opposed to waiting to initialize the UI until after the list of objects is built. It ensures that your application will always be responsive for the user.
Because you only have 0.5 sec to execute onCreate — after which the dreaded ADN (application not responding) error message is displayed. So unless your list view is super simple you won't make it it in time. And even if your list view is super simple it is better to learn it the proper way.
BTW: I don't even use threads, I use one or more Services to do all the work. Even more difficult to implement but more robust and responsive as well.
The reason you don't do things in onCreate or on the UI thread is for responsiveness. If your app takes too long to process, the user gets shown an App Not Responding dialog.
my teacher once said: every software can be written in a single (big) for loop.
And if you think: it can be... maybe at NDK level.
Some SDK developers wanted to make the software developers tasks easier and that's, why exists the SDK's and frameworks.
Unless you don't need anything from multitasking you should use single threading.
Sometimes there are time limitations, sometimes UI/background/networking limitations and need to do stuff in diff threads.
If you see source code of Asyntask and Handler, you will see their code purely in Java. (of course, there some exceptions, but that is not an important point).
Why does it mean ? It means no magic in Asyntask or Handler. They just make your job easier as a developer.
For example: If ProgramA calls methodA(), methodA() would run in a different thread with ProgramA.You can easily test by:
Thread t = Thread.currentThread();
int id = t.getId();
And why you should use new thread ? You can google for it. Many many reasons.
So, what is the difference ?
AsyncTask and Handler are written in Java (internally use a Thread), so everything you can do with Handler or AsyncTask, you can achieve using a Thread too.
What Handler and AsyncTask really help you with?
The most obvious reason is communication between caller thread and worker thread. (Caller Thread: A thread which calls the Worker Thread to perform some task.A Caller Thread may not be the UI Thread always). And, of course, you can communicate between two thread by other ways, but there are many disadvantages, for eg: Main thread isn't thread-safe (in most of time), in other words, DANGEROUS.
That is why you should use Handler and AsyncTask. They do most of the work for you, you just need to know what methods to override.
Difference Handler and AsyncTask: Use AsyncTask when Caller thread is a UI Thread. This is what android document says:
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers
I want to emphasize on two points:
1) Easy use of the UI thread (so, use when caller thread is UI Thread).
2) No need to manipulate handlers. (means: You can use Handler instead of AsyncTask, but AsyncTask is an easier option).
There are many things in this post I haven't said yet, for example: what is UI Thread, of why it easier. You must know some method behind each kind and use it, you will completely understand why..
#: when you read Android document, you will see:
Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue
They may seem strange at first.Just understand that, each thread has each message queue. (like a To do List), and thread will take each message and do it until message queue emty. (Ah, maybe like you finish your work and go to bed). So, when Handler communicates, it just gives a message to caller thread and it will wait to process. (sophiscate ? but you just know that, Handler can communicate with caller thread in safe-way)

Android AsyncTask for long running operations

Quoting the documentation for AsyncTask found here, it says:
AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and FutureTask.
Now my question arises: why? The doInBackground() function runs off the UI thread so what harm is there by having a long running operation here?
It is a very good question, it takes time as an Android Programmer to fully understand the issue. Indeed AsyncTask have two main issues that are related :
They are poorly tied to the activity life cycle
They create memory leaks very easily.
Inside the RoboSpice Motivations app (available on Google Play) we answer that question in detail. It will give an in-depth view of AsyncTasks, Loaders, their features and drawbacks and also introduce you to an alternative solution for network requests : RoboSpice.
Network requests are a common requirement in Android and are by nature long running operations
.
Here is an excerpt from the app :
The AsyncTask and Activity life cycle
AsyncTasks don't follow Activity instances' life cycle. If you start an AsyncTask inside an Activity and you rotate the device, the Activity will be destroyed and a new instance will be created. But the AsyncTask will not die. It will go on living until it completes.
And when it completes, the AsyncTask won't update the UI of the new Activity. Indeed it updates the former instance of the activity that
is not displayed anymore. This can lead to an Exception of the type java.lang.IllegalArgumentException: View not attached to window manager if you
use, for instance, findViewById to retrieve a view inside the Activity.
Memory leak issue
It is very convenient to create AsyncTasks as inner classes of your Activities. As the AsyncTask will need to manipulate the views
of the Activity when the task is complete or in progress, using an inner class of the Activity seems convenient : inner classes can
access directly any field of the outer class.
Nevertheless, it means the inner class will hold an invisible reference on its outer class instance : the Activity.
On the long run, this produces a memory leak : if the AsyncTask lasts for long, it keeps the activity "alive"
whereas Android would like to get rid of it as it can no longer be displayed. The activity can't be garbage collected and that's a central
mechanism for Android to preserve resources on the device.
It is really a very very bad idea to use AsyncTasks for long running operations. Nevertheless, they are fine for short living ones such as updating a View after 1 or 2 seconds.
I encourage you to download the RoboSpice Motivations app, it really explains this in-depth and provides samples and demonstrations of the different ways to do some background operations.
why ?
Because AsyncTask, by default, uses a thread pool that you did not create. Never tie up resources from a pool that you did not create, as you do not know what that pool's requirements are. And never tie up resources from a pool that you did not create if the documentation for that pool tells you not to, as is the case here.
In particular, starting with Android 3.2, the thread pool used by AsyncTask by default (for apps with android:targetSdkVersion set to 13 or higher) has only one thread in it -- if you tie up this thread indefinitely, none of your other tasks will run.
Aysnc task are specialized threads that are still meant to be used with your apps GUI but whilst keeping resource-heavy tasks of the UI thread. So when stuff like updating lists, changing your views etc require you to do some fetch operations or update operations, you should use async tasks so that you can keep these operations off the UI thread but note that these operations are still connected to the UI somehow.
For longer-running tasks, which don't require UI updation, you can use services instead because they can live even without a UI.
So for short tasks, use async tasks because they can get killed by the OS after your spawning activity dies (usually will not die mid-operation but will complete its task). And for long and repetitive tasks, use services instead.
for more info, See threads:
AsyncTask for longer than a few seconds?
and
AsyncTask won't stop even when the activity has destroyed
The problem with AsyncTask is that if it is defined as non-static inner class of the activity, it will have a reference to activity. In the scenario where activity the container of async task finishes, but the background work in AsyncTask continues, the activity object will not be garbage collected as there is a reference to it, this causes the memory leak.
The solution to fix this is define async task as static inner class of activity and use weak reference to context.
But still, it is a good idea to use it for simple and quick background tasks. To develop app with clean code, it is better to use RxJava to run complex background tasks and updating UI with results from it.

ASyncTask does not execute when task.execute() is called

I have an Android application which has the main UI thread, and several other worker threads which I have spawned using ASyncTask.
However, there is a scenario that I can produce every time in which I attempt to spawn a new thread with ASyncTask using task.execute(), and it does not call doInBackground(). The thread never seems to start. Then my application seems to spin for a little while, and then begins to hang.
Here are the threads I am using:
And here is the memory usage on the device:
It does not look as though it is failing to spawn due to memory issues.
Is there some other underlying reason that I do not know of? Maximum number of threads? Is there any way for me to find out why it is not executing?
AsyncTask uses a ThreadPoolExecutor used internally with a core pool size of 5 and a LinkedBlockingQueue. In simpler terms: you can have atmost 5 AsyncTasks active at the same time. Additional tasks will be queued till one of the other AsyncTasks does not return from doInBackground().
You may want to review your code to free up some AsyncTasks. If thats not possible, you can try to create a CustomAsyncTask class in your project based on the original AsyncTask code which can be found here. Try setting the CORE_POOL_SIZE variable to a higher value or using a SynchronousQueue.
Did you read the docs?
Note: this function schedules the task on a queue for a single
background thread or pool of threads depending on the platform
version. When first introduced, AsyncTasks were executed serially on a
single background thread. Starting with DONUT, this was changed to a
pool of threads allowing multiple tasks to operate in parallel. After
HONEYCOMB, it is planned to change this back to a single thread to
avoid common application errors caused by parallel execution. If you
truly want parallel execution, you can use the
executeOnExecutor(Executor, Params...) version of this method with
THREAD_POOL_EXECUTOR; however, see commentary there for warnings on
its use.
Source

Categories

Resources