Section 1th Threading Overview
There is only one main thread for Android apps-each component runs in this thread. As one of the components of the activity is to update the application interface in this thread, for example, the user click on a button on the interface, the button is responsive, the whole process is in the main thread. So the main thread can never do a time-consuming operation . If you do a time-consuming operation in a button, then when it takes time to operate, you can click on the other buttons on the interface without reacting, as if the program froze there.
Once our code continues to occupy this thread for more than a certain amount of time, the system pops up a "program unresponsive" hint called ANR -applicatin no Response.
It's like you're doing something. A, suddenly another thing B to disturb you, you have to stop the work to finish, you have to finish before you can continue to work, then if there is another person (another thread) to help you, to do all the things B, then you do not have to distract. When another person finishes B, let you know.
Starting a new thread and sharing the time-consuming work is an asynchronous operation: I asked you to help me do one thing, after the assignment, I went to do other things, when you finished to tell me the result;
And it corresponds to the synchronous operation: I asked you to help me do one thing, after the assignment, I do nothing, just wait for you to finish tell me the result;
For example, a video playback app, the time it takes to get video information is an uncertain thing. If the video is very small, maybe dozens of milliseconds to complete, if a lot of video (such as dozens of), it may take more than 20 seconds.
Therefore, we can consider putting the operation of acquiring video information into a separate thread. Start a new thread-worker thread thread-query video information, after the query is completed, the worker thread then notifies the main thread of the result, allowing the main thread to display the results of the query to the interface. Because the interface updates must be made in the main thread, cannot be modified in another thread, or the system will be prompted to run the error. Therefore, we must send the results of the query to the main thread, so that the main thread processing interface updates.
This involves the creation of threads, the assignment of work, and the coordination between them-the passing of information.
Section 2nd Threads Thread
An activity running on a main thread does not take much time and does not perform time-consuming and indeterminate operations. As a result, these time-consuming operations are required in a new thread, which is called a worker thread.
Simple use of 2.1 thread
Create a new thread,
Create a Runnable function that overrides it run() , which is used for time-consuming operations;
@Override publicvoidrun() { //耗时的操作 while(xxx) { } }};
As Runnable a parameter, create one Thread , call Thread the start() method after the new thread has run up, and execute the Runnable function in run() ;
new Thread(runnable);thread.start();
When run() the function is finished, the new thread exits;
Sometimes it is time to cancel the operation of this thread during the process of executing
The best way to run() do this is to add a flag bit to the function, and the worker thread will check to see if the flag bit is set at any time, and if it is set, let the run() function return immediately.
//设置标志位,为退出线程使用booleanfalsenew Runnable() { @Override publicvoidrun() { //耗时的操作 while(!needStop) { } }};
If the main thread is going to cancel the work of this one, it will be fine to modify this flag bit.
needStop = true;
2.2 Thread Creation
Thread can have different priorities, from low to high with 10 levels. The operating system makes resource scheduling based on the priority of the thread, prioritizing the CPU resources for high-priority threads. By default, the newly created thread uses the default priority NORM_PRIORITY . The way to set priorities is simple,
Threadthread=newThread(runnable);thread.setPriority(Thread.NORM_PRIORITY);
You can name the thread, and when we use Android Monitor the tool to debug the application, we can see the name of the thread when it was created, which allows us to observe and debug the program.
Threadthread=newThread"新线程的名字");
Sometimes an app starts multiple threads at the same time, and when they are created, they can be set up with ThreadGroup parameters that are grouped together to allow for uniform management of the thread. For example, to interrupt the operation of all threads in this group;
new ThreadGroup("线程组"newnewnew Thread(runnable, group);thread3.start();//中断3个线程的执行group.interrupt();
2.3 Thread's Stop
The stop of thread means the exit of this thread. There are two reasons why a thread exits,
- The work of the worker thread has been completed;
- The worker thread is in a time-consuming job, but is canceled and ends prematurely;
2.3.1 Normal exit
When Runnable the run() function is finished and returned, the current thread exits.
2.3.2 Using flag bits
run()add a flag bit to the function, and the worker thread will check to see if the flag bit is set, and if it is set, let the run() function return immediately.
//设置标志位,为退出线程使用booleanfalsenew Runnable() { @Override publicvoidrun() { //耗时的操作 while(!needStop) { } }};
If the main thread is going to cancel the work of this one, it will be fine to modify this flag bit.
true;
2.3.3 using the Interrupt () method
interrupt()is a standard thread exit method provided by the thread, and if the current worker thread is being Object.wait , Thread.join or Thread.sleep blocking, the thread.interrupt() running thread throws an exception after use InterruptedException .
new Runnable() { @Override publicvoidrun() { ... while(!needStop) { try { ...... Sleep(1000); catch ( InterruptedException e ) { true } } }};
However interrupt() , the method is not all-purpose, not all blocking situations can let the thread exit immediately.
For example, if the thread is using ServerSocket a method that waits for a accept() connection, interrupt() the thread will not throw an exception even if the worker thread is called.
It only Object.wait works for, Thread.join or Thread.sleep these kinds of blockages. For the network read Data era blocking state cancellation is ineffective.
* For blocking when the network reads data, we will detail the workaround in the appropriate section later.
2.4 Synchronization between threads
Synchronization between threads means that when thread a executes to a place, it stops, waits for the result of thread B's execution, and thread A can continue execution after the result is executed by thread B.
2.4.1 Join () method
The most common is the execution of the main thread, which relies on the exit of the worker thread.
After the main thread has started the worker threads, it is sometimes necessary to wait until the end of the worker thread to perform the next operation.
An activity, for example, onCreate() creates a worker thread at the time of thread B; Then, at the user's request, the activity exits and is destroyed; When the activity is destroyed, the main thread waits until thread B is finished to continue with the rest of the cleanup work. , activity can use the method in its OnDestroy () function join() , waiting for the end of the child thread,
private Thread mTreadB;@OverrideprotectedvoidonCreate() { super.onCreate(); new Thread(runnable); mThreadB.start();}@OverrideprotectedvoidonDestroy() { super.onDestroy(); mThreadB.join(); //进行剩下的清理操作}
join()method, it will remain blocked until thread B exits.
There is a natural disadvantage to using in: it is not possible to take time-consuming and uncontrolled operations in the onDestroy() join() main thread (for example, waiting for a worker thread to finish), and if the worker's exit takes a long time, then there is a problem. The scene here is just to give an example.
2.4.2 Wait () method
Objectthe method used to wait() implement synchronization between threads requires a "lock"-object to be shared between threads Object .
finalnew Object();
When the main thread a executes to a stage, if you want to wait for thread B, the lock is placed in a wait state.
lock.wait()
At this point, thread A is in a blocked state and cannot be executed down.
Thread B continues its run, and when it executes to a stage, the lock is set to the release state,
lock.notify();
At this point, the blocking state of thread A is lifted, and you can continue to execute down.
multithreaded development (i)-Threads for Android systems