Android multithreading - How can I customize consuming Runnables in a BlockingQueue? - android

I'm currently learning Android programming and I'm doing my first application using VS 2017 in C# (Xamarin). Right now I'm trying to understand how to split a complex computation into several threads - more accurately, the features I should look into.
Now, what I want to do is to iterate over all possible values of an unsigned int and perform some computation on it. It's a search, so some of those numbers will be of interest and I need the threads to update a progress bar and some view containing any results found so far. The complexity here is the huge number of operations that will be performed.
I've looked into Async Tasks, Thread Pool Executor, Thread Factory, Blocking Queues and Runnables. So I'm thinking a Thread Pool sounds like the way to go, especially by specifying how many processors are available and how many threads can be used.
Going by this SO question/answer, I would use an Async Task for a short operation and Java threads for more complex operations. So, despite using C# Xamarin, I guess I'm looking into Javal.Util.Concurrent.Thread's..
My goal with all this, is to allow the user to start this complex task and pause it at any point, or abort, as well as save the search state at any point to resume later. To do this, I want to subdivide this search on all possible uint values into multiple tasks - perhaps thousands of small tasks that could be executed by worker threads. For the pause feature, I was thinking the example in Android's documentation, that I previously linked, which implements Pause/Resume methods in a custom Thread Pool Executor. The save/store should be easy.. if my tasks are ordered all I need is to keep track of the last value tested and fruitful values.
I've setup a custom Thread Pool Executor, Factory and Runnables. However, I am quite confused as to how to do two things:
How exactly should I add runnables to the queue? And from which thread?
How, and where, do I know when the search was completed? What happens to the minimum number of threads in the Thread Pool Executor when the job is completed? I want to destroy all the threads when it's over.
In my operations I could have thousands of tasks. In fact, I can decide between 4096 large tasks, or 65536 smaller tasks. They can be identified by a range of uints to be checked, or a single uint index. But either way I know ahead of time how many they are and I think it would be more efficient if I didn't have to create that many runnables... Is there a way I can customize how the threads will pick up their next work from the Queue?
Or perhaps the Thread Pool Executor is just not the right tool for what I'm trying to achieve here?
I'm mostly looking for some insight on the multithreading tools available in Android and how can I go about implementing a proper solution for my problem.

You should definitely have a look to reactive programming http://reactivex.io/ and https://github.com/ReactiveX/RxJava
This is the best and cleanest way to execute tasks in background, for example you could do :
myObservable
.subscribeOn( Schedulers.io() ) // Thread where you execute your code
.observeOn( AndroidSchedulers.mainThread()) / Thread where you get result
.subscribe(...)

Related

RxJava: How to select the proper Scheduler

I'm learning RxJava and I have some doubts regarding the Scheduler.
When to use which one. The AndroidSchedulers.mainThread() is quite easy and clear,
whenever we need to come to the Android UI thread, we can use this scheduler.
But I'm confused with the other Schedulers
Schedulers.io()
Schedulers.computation()
Schedulers.newThread()
In many samples I have seen pepople using Schedulers.io() and Schedulers.computation() for network calls ,
db operations etc. Can we pick any of them randomly for background tasks?
If not which are the suitable situations to pick each? When to use Schedulers.newThread()?
It would be helpful if someone could explain it in simple words. Thanks in advance!!
io(): When you want to perform I/O bound work like database requests, network calls etc. use io. This scheduler is backed by an unbounded thread pool(which may cause OutOfMemory error if you go crazy with number of threads you are using). What it essentially means is that you don't get the overhead of creating a new thread every time. See more Why is creating thread expensive?
newThread(): As the name implies, it will create a new thread every single time.
computation: If you have some expensive CPU bound operation, you should use this Scheduler. This scheduler is bounded i.e there a limited number of threads based on the system.
As other have pointed out, please take a look at official documentation to understand more here

Android: Future/FutureTask for parallel processing of data

I am trying to optimize a complex data updater and parser for my Android app. The server provides three interface functions. The parser requires the data from all those three functions.
When the download of the data is finished, the parser can start. It consists of many different independent tasks which can be parallelized.
I was thinking of using Futures or FutureTasks for processing the data.
So basically, this is the procedure:
create Task-1, Task-2, Task-3 for downloading the data
wait for the downloads to be finished
create Task-1,..., Task-N for parsing the data
wait for the parser to be finished
call a callback to signal that process is done.
My first question: is it possible to create Futures with asynchronous functions, which use callbacks to return the data (network framework)?
Second question: are there any drawbacks in using Futures or FutureTasks respectively in this scenario or are there any better solutions to achieve that?
Thank you.
Basically you are Trying to achieve the following.
Step 1 - User from UI starts 1,2,... n download tasks.
Step 2 - Once each of the task is completed, new thread should be started to process it.
Step 3 - Once all n Tasks are completed, UI should be updated ... may be with a success dialog.
This can be achieved easily by using Async Task. I am going to tell you the approach and not the code sample.
Things to note about Async Task
Before 1.6, Async Task handles all background operations with a single additional thread.
After 1.6 till 3.0 .. it was changed, so that a pool of thread had begun to be used. And operations could be processed simultaneously.
Since Honeycomb default behavior is switched back to use of a single worker thread (one by one processing).
How to implement your requirement
For your requirement, you can use the method (executeOnExecutor) to run simultaneous tasks (1 till n tasks) if you wish (there two different standard executors: SERIAL_EXECUTOR and THREAD_POOL_EXECUTOR).
The way how tasks are enqueued also depends on what executor you use. In case of a parallel one you are restricted with a limit of 10 (new LinkedBlockingQueue(10)). In case of a serial one you are not limited (new ArrayDeque()).
So the way your tasks are processed depends on how you run them and what SDK version you run them on. As for thread limits, we are not guaranteed with any, yet looking at the ICS source code we can say that number of threads in the pool can vary in range 5..128.
When you start too many tasks (like 100s or more) with default execute method serial executor is used. Since tasks that cannot be processed immediately are enqueued you get OutOfMemoryError (thousands of tasks are added to the array backed queue).
Exact number of tasks you can start at once depends on the memory class of the device you are running on and, again, on executor you use.
So by following this approach, once all the tasks are completed, you can use a handler to update the UI.
Hope this helps.

When to use ThreadPoolExecutor instead newThread()

I have a http server which is gonna be really busy, there are few HttpHandlers inside it which all of them start their job with a new Thread() , since i still can not compeletely understand ThreadPoolExecutor's Usage (When you should use, when no need to), i really could use a little tip about it and do i need to use one?
Plus is there any roof for the threadPoolExecutor's max Threads ?
Same goes for the android, i dont understand why should i use ThreadPoolExecutor instead simply use newThread()?
Basically ThreadPoolExecutor is just a high level API from java to do task in multiple thread without dealing with low level API (Creating thread manually)
For a little example a ExecutorService executor = Executors.newFixedThreadPool(5); will run the tasks you submit in 8 threads.
You can try to understand it more by reading this documentation.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
and this tutorial
http://tutorials.jenkov.com/java-util-concurrent/threadpoolexecutor.html
you must use ThreadPoolExecutor when you do not know how many times your new Thread() will be called because you have limited resources if you let unlimited call to new Thread() you will get in trouble like out of memory exception. in restricted world like android it is necessary to know how many times you create thread and if it is not in control of you for example your user input determines the creation of thread you must use ThreadPoolExecutor.
Creating and destroying threads has a high CPU usage, so when you need
to perform lots of small, simple tasks concurrently the overhead of
creating your own threads can take up a significant portion of the CPU
cycles and severely affect the final response time. This is especially
true in stress conditions where executing multiple threads can push
CPU to 100% and most of the time would be wasted in context switching
(swapping threads in and out of the processor along with their
memory).

Should Calculations be done in SurfaceView or seperate Thread

So over the last few months I've created a fairly complex game that's near ready for release. The only problem left is that it is running as smoothly as I would hope and I think this is because of the way I have structured my threads. Right everything in my code is done through a surfaceview. All calculations, position updates, drawing, collisions, etc are done there. I was wondering if I am supposed to put all updates into one thread then handle only drawing in the surfacethread. Is this the proper way to do it, if so how would i implement that(asynctask,thread,handler,etc)?
Sure, you should avoid doing any time-consuming calculation in the UI Thread. You could also incur in an ANR error message.
You can either use:
AsyncTask, but be aware that it has some flaws and drawbacks. For example it isn't guaranteed to even start or complete.
IntentServices or HandlerThreads if you need to do operations that need to be executed sequentially in a worker thread
WorkerThreadPool if you need to execute true parallel tasks.

Performance comparison: AsyncTasks vs Threads

In my app, I have to call a method which does some heavy work (I can feel device lagging). To avoid this I created an AsyncTask and it works perfectly fine.
I implemented the same thing using a Thread and here, too, it does not give any hiccup and works fine.
Now my question is which one better performance-wise - AsyncTask or Thread.
I know AsyncTask uses a threadpool to perform background tasks but in my case it will be called only once. So I don't think it will create any problems.
Can someone throw some light on it. Which one should I use for better performance?
Note: Both are being called in my Activity e.g. from UI the thread.
Can someone throw some light on it. Which one should I use for better
performance?
I think if you imagine case when you start once native Thread and AsyncTask i think that performance won't differ.
Usually native threads are used in the case if you don't want to inform potential USER with relevant information about progress in some task via UI. Here, native threads fail because they are not synchronized with UI thread and you cannot perform manipulating with UI from them.
On the other hand, AsyncTask combines background work with UI work and offers methods which are synchronized with UI and allow performing UI updates whenever you want via invoking proper methods of its lifecycle.
Generally if some task lasts more than 5 seconds you should inform USER that
"something working on the background, please wait until it will be finished"
For sure, this can be reached with both in different ways but this strongly depends on character of your task - if you need to show progress of task(how much MB is already downloaded, copying number of files and show name of each in progress dialog etc.) or you don't(creating some big data structure in "silent" only with start and end message for instance).
So and at the end of my asnwer:
Which one should I use for better performance?
Completely right answer i think you cannot get because each developer has different experiences, different coding style. How i mentioned, their performance not differ. I think that it's same(if you will read 50 MB file, it won't be faster read neither native thread nor AsyncTask). It depends again on character of task and your personal choice.
Update:
For tasks that can last much longer periods of time, you can try to think also about API tools provided by java.util.concurrent package(ThreadPoolExecutor, FutureTask etc.)
Async tasks are also threads. But they have some utility methods that make it very easy to small background tasks and get back to the UI to make changes to it. The performance would depend on your specific use case. Making absolute statements as to which one is always better would be simplistic and meaningless.
Note that the main advantage of Async tasks over threads is that Async tasks provide helper methods such as onPreExecute(), doInBackground(), onProgressUpdate() and onPostExecute() which make it very easy to perform short background tasks while also interacting with the UI (such as updating a progress bar). These kinds of methods are not available in generic Threads. Basically, Async tasks are threads with UI interaction component built in. Yes, you can use workarounds to try and update the UI from regular threads as well but Async tasks have been specifically built for this purpose and you don't have to deal with Context leaks and so on if you follow it's abstractions.
Async tasks are created to make developers' lives easier.
To sum up:
Async tasks are also threads
Async tasks make it easy to interact with UI while doing short background tasks
Neither is inherently more efficient. It depends on what you want to do.
Good rule of thumb: Use Async tasks if you need to get back to/update the UI after you are done with your background task. Use a regular thread if you don't.
The most common use of Thread are short-term tasks because they need a lot of power and tend to drain the battery and heat the phone up.
And the common use of AsyncTasks are lengthy tasks because of the same battery drain.
But a Thread is far more powerfull, because an AsyncTasks internally uses a Thread itself, but you don't have to configure that much.
ASYNC TASK and Thread do the same thing,
The difference is that you have more control on bare thread and you can benefit from the power of CPU in terms of complex implementation, the velocity of performance depends on your approach on how you implement the threading.
Depending on this article I can say that asynchronous multithreading is the fastest way to perform complex tasks.
https://blog.devgenius.io/multi-threading-vs-asynchronous-programming-what-is-the-difference-3ebfe1179a5
Regarding showing updates to user on UI thread, you can do that by posting on UI from the background thread (check UIhandler and View.Post)

Categories

Resources