What are the benefits to use Schedulers.newThread() vs Schedulers.io() in Retrofit network request. I have seen many examples that use io(), but I want to understand why.
Example situation:
observable.onErrorResumeNext(refreshTokenAndRetry(observable))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())...
vs
observable.onErrorResumeNext(refreshTokenAndRetry(observable))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())...
One of the reasons i have seen is -
newThread() creates a new thread for each unit of work. io() will use a thread pool
But what is the influence of that argument on the app? And what other aspects there are?
You are correct that the benefit of using Schedulers.io() lies in the fact that it uses a thread pool, whereas Schedulers.newThread() does not.
The primary reason that you should consider using thread pools is that they maintain a number of pre-created threads that are idle and waiting for work. This means that when you have work to be done, you don't need to go through the overhead of creating a thread. Once your work is done, that thread can also be re-used for future work instead of constantly creating and destroying threads.
Threads can be expensive to create, so minimizing the number of threads that you are creating on the fly is generally good.
For more information on thread pools, I recommend:
What is the use of a Thread pool in Java?
What is a thread pool?
Thread pool pattern (Wikipedia)
Related
I have a couple questions on kotlin coroutines.
how many thread could get involved when working with coroutines?
if we use just Dispatchers.Main, would only one thread get involved(single threaded)? if we use Dispatchers.IO, would multiple thread possibly get involved (maximum of 64 threads)?
what will be the use case for using Dispatchers.Main? most articles that I have read say all UI related works should present in Dispatchers.Main and background related works(like reading/writing data from/to database, network requests) needs to present in Dispatchers.IO but I don't understand what UI related works present in Dispatchers.Main since UI related work don't really necessary need coroutines (with Dispatchers.Main)
we use susepnd fuction with coroutines for some works that could block the current thread. For example, read data from disk, network requests, or high tense computation etc. if these works are executed by suspend function, what/who is in charge when these functions are suspended? I think something has to be working on these suspend functions anyway. will that be background threads that is in charge of below?
reading/writing data from/to databse
waiting for network request
computing high tense computation
please point out if my wording or questions are incorrect.
Thank you in advance.
I think you answered yourself. Short answer is: Dispatchers.Main - single thread, Dispatchers.Default - number of cores, Dispatchers.IO - at most 64. You can read about it here. Full answer is a little more complicated as limits could be reconfigured, they may differ on different platforms (e.g. JavaScript is always single-threaded), Default partially shares threads with IO, etc. We can also create our own thread pools.
I'm not sure what do you mean. Coroutines are generally never necessary in order to do anything. But if we use coroutines inside UI application, then we should use Dispatchers.Main for UI-related stuff.
We should almost never use blocking code inside coroutines (one exception is Dispatchers.IO). If we do that, the coroutine won't suspend, but just block, possibly making other parts of our application unresponsive or degrading the performance.
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(...)
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
In my app, I need to make a number of TCP socket calls.
To be able to do this, I have to do the following steps:
1. convert my data/command into a byte stream
2. create socket and send command and receive response
3. parse response and store for UI to use.
Now I have created a background thread to be able to do all three steps.
But in my socket client also I want to create a new thread for each new command (Step# 2)
So that would mean that I have a number of worker threads inside the common worker thread for all the three above steps.
So, would it be ok to use Async task for step #2 which is already taking place in a worker thread. Or do I use normal thread in this case.
One might wonder why am i not achieving all three steps in one worker thread.
The point is that even if I create just one worker thread for all the socket commands, there is a possibility that the initial request for step 1 might itself come from a worker thread.
Hence, I cannot just assume that the call is from Main UI thread.
Also, I wanted to ask whether it is not recommended to create your own worker threads in android and why?
Thanks,
Sunny
Form your first 2 paragraphs i understand you want to establish some communication via sockets. i dont believe it would be a good approach to create a thread per command as thread itself and opening/closing sockets are expensive operations.
i would suggest creating only one thread for opening and monitoring/writing/reading data to/from socket. if these commands are frequent than maintaining one socket alive is more appropriate than frequently opening/closing sockets. optionally i would create an extra thread for doing the extra work of serializing/deserializing commands (if they r time-consuming).
One might wonder why am i not achieving all three steps in one worker thread. The point is that even if I create just one worker thread for all the socket commands, there is a possibility that the initial request for step 1 might itself come from a worker thread.
I dont think it would make a big difference in your design approach where the requests come from.
Hence, I cannot just assume that the call is from Main UI thread. Also, I wanted to ask whether it is not recommended to create your own worker threads in android and why?
Android provides some very good generic classes such as AsyncTask and HandlerThread for general purpose usages but anyone is free to create a worker thread if the above ones do not fit the design requirements. Personally i create my own worker threads if i deal with socket programming.
I would suggest taking a look at Java NIO library specifically Selectors, and SocketChannel classes
You cannot use AsyncTask for that.
AsyncTasks can only be instantiated and executed on the UI thread.
You can, however, use standard threads.
class MyThread {
#override
public void run() {
......
// when needed - span a new working thread fro within old one
new MyOtherThread(...).start();
}
}
No problems here.
if you feel the number of threads you are spawning may go out of control, it is a smart idea to use a thread pool. The java.util.concurrent package has several, e.g.
ThreadPoolExecutor.
Finally, and I have give this recommendation several times before, if your task
is to transmit a large amount of small object using a multi threaded architecture,
using Volley is probably the most effective way to go.
Good luck.
I have question which puzzles me.
Imagine I wanna do something in another thread, like fetching GPS/Location stuff, which as recommended in the SDK documents, must use a background thread.
So here is the question: What's the difference between
Creating a Thread in background via AsyncTask AND
Creating Thread thread1 = new Thread(new Runnable() ... and implementing run()?
AsyncTask is a convenience class for doing some work on a new thread and use the results on the thread from which it got called (usually the UI thread) when finished. It's just a wrapper which uses a couple of runnables but handles all the intricacies of creating the thread and handling messaging between the threads.
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.
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.
An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
The Runnable interface is at the core of Java threading. The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread.
Also if I quote from this blog:
if you need SIMPLE coding use AsyncTask and if you need SPEED use traditional java Thread.
Key differences:
AsyncTask is an asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. It can't be done with normal thread unless you use Handler on UI Thread and post a message OR directly change attribute of an object by implementing proper synchronization.
As recommended by developer guide regarding Thread performance,
There are a few important performance aspects to keep in mind. First, by default, an app pushes all of the AsyncTask objects it creates into a single thread. Therefore, they execute in serial fashion, and—as with the main thread—an especially long work packet can block the queue. For this reason, we suggest that you only use AsyncTask to handle work items shorter than 5ms in duration..
But normal Thread can be used for long running tasks.
Plain java Threads are not much useful for Android unlike HandlerThread, which has been provided by Android framework.
Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.
Refer to below post to know more details:
Handler vs AsyncTask vs Thread
Also take in count that starting on Android v4.04, you can't have more than one AsyncTasks at a time, unless you lose compatibility with lower versions. Be aware!
AsyncTask deprecated with api level 30. Using thread/runnable is convenient
One obvious drawback for AsyncTask class is that after Android 3.0 asynctasks are executed according to the sequence of the start time. that is tasks are executed one by one, unless you execute the task by calling 'executeOnExecutor(Executors.newCachedThreadPool())'. this method would create your own thread pool.
Better to use the new Job Scheduler in the support library.