When it comes to threads, we need to talk about the thread mechanism. Handler, Looper, MessageQueue can be said to be three mountains.
Handler
Handler is actually a handler, or a sender, which will send the message to the message queue, that is, Looper, and then perform the operation of fetching the message in an infinite loop queue (mMessage); This sentence means that I have finished processing the operation and I have sent it! Then process it in the place where I accept it! Is it simple to understand?
How do we usually do asynchronous operations in projects?
// Open a child thread here for time-consuming operations new Thread() { @Override public void run() { ....... Message mMessage = new Message(); = 1; //Send it to the message queue here (mMessage); } }.start(); /** * This is the place to deal with it */ class MyHandler extends Handler{ @Override public void handleMessage(Message msg) { (msg); switch (){ //Fetch out the corresponding message for processing ........ } } }
So where is our message queue started? Follow the source code to take a look
# public static void main(String[] args) { //Omit the code. . . . . //A message queue was created here! (); ActivityThread thread = new ActivityThread(); (false); if (sMainThreadHandler == null) { sMainThreadHandler = (); } //I don't understand this sentence, isn't it impossible to execute it all the time if (false) { ().setMessageLogging(new LogPrinter(, "ActivityThread")); } (Trace.TRACE_TAG_ACTIVITY_MANAGER); //The message queue is running! (); throw new RuntimeException("Main thread loop unexpectedly exited"); }
public Handler(Callback callback, boolean async) { mLooper = (); // Pay attention to the exception thrown here. If mLooper==null if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called ()"); } //Get message queue mQueue = ; mCallback = callback; mAsynchronous = async; }
The above operation of the Android system obtains and starts a message queue. Too much source code is not to be described here, and it will not take up a lot of space.
Here is a common question for the trial below, which is whether you can create a Handler in a child thread. It is actually OK, but who can use it like this - -
new Thread() { Handler mHandler = null; @Override public void run() { //Get here (); mHandler = new Handler(); //Start here (); } }.start();
Multithreaded creation
Generally, when we start a thread during development, we will do it directly.
new Thread() { @Override public void run() { doing..... } }.start();
new Thread(new Runnable() { @Override public void run() { doing..... } }).start();
Note that one passes the Runnable object, the other does not, but what is the difference between these two, why do you need to derive two?
I won’t look at the source code here, let’s briefly describe it. In fact, Thread is a package implementation class for Runnabled. Runnable has only one method, which is run(). I have thought about it before. Why is Runnable only one method? I found an answer in a conversation later. Maybe it’s because of the expansion. Maybe the JAVA language wants to expand some other things, so I will write it directly in Runnable in the future. Otherwise, I didn't think of another answer why I had to pass a Runnable, maybe just like the baseActivity we developed
Common operation methods for threads
- wait() When a thread executes wait(), it will enter a waiting pool related to the object, and at the same time it loses the machine to release the current object, so that other threads can access it, that is, other threads can call notify() to wake up.
- sleep() calls the thread to enter a sleep state. It cannot change the object's machine lock and other threads cannot access it.
- Join() just wait for yourself to finish
- yidld, you're anxious, come first
This is actually the simple vernacular narrative. I hope I can take a look at the demo and understand it.
Some other methods, Callable, Future, FutureTask
Runnable is an extension interface for thread management and cannot be used in thread pools, so you must have a method to manage in thread pools. So Callable, Future, FutureTask is an interface for opening threads in thread pools.
Future defines the standard interface, such as get(), isDone(), isCancelled()... FutureTask is his implementation class. Here I briefly talk about its usage.
/** * ================================================================ * Author: Xia Muyao Github address: /XiaMuYaoDQX * Version: 1.0 * Created date: 2018/1/10 * describe: * Revised history: * ================================================================ */ class FutureDemo { //Create a singleton thread static ExecutorService mExecutor = (); public static void main(String[] args) throws ExecutionException, InterruptedException { ftureWithRunnable(); ftureWithCallable(); ftureTask(); } /** * No return value is specified, so the return is null, and the Runnable submitted to the thread pool is * * @throws ExecutionException * @throws InterruptedException */ private static void ftureWithRunnable() throws ExecutionException, InterruptedException { Future<?> result1 = (new Runnable() { @Override public void run() { fibc(20); (().getName()); } }); ("Runnable" + ()); } /** * Callable is submitted, with a return value, and the blocking thread can get the value obtained * * @throws ExecutionException * @throws InterruptedException */ private static void ftureWithCallable() throws ExecutionException, InterruptedException { Future<Integer> result2 = (new Callable<Integer>() { @Override public Integer call() throws Exception { (().getName()); return fibc(20); } }); ("Callable" + ()); } /** * Submitted futureTask object * @throws ExecutionException * @throws InterruptedException */ private static void ftureTask() throws ExecutionException, InterruptedException { FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() { @Override public Integer call() throws Exception { (().getName()); return fibc(20); } }); (futureTask); ("futureTask" + ()); } private static int fibc(int num) { if (num == 0) { return 0; } if (num == 1) { return 1; } return fibc(num - 1) + fibc(num - 2); } }
Thread pool
Java provides thread pools through Executors, which are:
- newCachedThreadPool creates a cacheable thread pool. If the thread pool length exceeds the processing needs, it can flexibly recycle idle threads. If there is no recycle, create a new thread.
- newFixedThreadPool Creates a fixed-length thread pool that can control the maximum number of threads concurrency, and the excess threads will wait in the queue.
- newScheduledThreadPool Creates a fixed-length thread pool that supports timed and periodic task execution.
- newSingleThreadExecutor Creates a single-threaded thread pool, which will only use a unique worker thread to execute tasks, ensuring that all tasks are executed in the specified order (FIFO, LIFO, priority).
Sample code
newCachedThreadPool
Create a cacheable thread pool. If the thread pool length exceeds the processing needs, you can flexibly recycle idle threads. If there is no recycle, create a new thread. The sample code is as follows:
public class ThreadPoolExecutorTest { public static void main(String[] args) { ExecutorService cachedThreadPool = (); for (int i = 0; i < 10; i++) { final int index = i; try { (index * 1000); } catch (InterruptedException e) { (); } (new Runnable() { public void run() { (index); } }); } } }
The thread pool is infinite. When the second task is executed, the first task has been completed, and the thread that executes the first task will be reused without creating a new thread every time.
newFixedThreadPool
Create a fixed-length thread pool that can control the maximum number of threads concurrency, and the excess threads will wait in the queue. The sample code is as follows:
public class ThreadPoolExecutorTest { public static void main(String[] args) { ExecutorService fixedThreadPool = (3); for (int i = 0; i < 10; i++) { final int index = i; (new Runnable() { public void run() { try { (index); (2000); } catch (InterruptedException e) { (); } } }); } } }
Because the thread pool size is 3, sleep 2 seconds after each task outputs index, so 3 numbers are printed every two seconds.
The size of a fixed-length thread pool is best set according to the system resources. Such as ().availableProcessors()
newScheduledThreadPool
Create a fixed-length thread pool that supports timed and periodic task execution. The sample code for delayed execution is as follows:
public class ThreadPoolExecutorTest { public static void main(String[] args) { ScheduledExecutorService scheduledThreadPool = (5); (new Runnable() { public void run() { ("delay 3 seconds"); } }, 3, ); } }
Indicates delay execution by 3 seconds.
The sample code is executed regularly as follows:
public class ThreadPoolExecutorTest { public static void main(String[] args) { ScheduledExecutorService scheduledThreadPool = (5); (new Runnable() { public void run() { ("delay 1 seconds, and excute every 3 seconds"); } }, 1, 3, ); } }
It means that the delay is performed every 3 seconds after 1 second.
newSingleThreadExecutor
public class ThreadPoolExecutorTest { public static void main(String[] args) { ExecutorService singleThreadExecutor = (); for (int i = 0; i < 10; i++) { final int index = i; (new Runnable() { public void run() { try { (index); (2000); } catch (InterruptedException e) { (); } } }); } } }
Here I will briefly describe various methods of thread management, and will explain it in the future.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.