Android custom thread pool practice and android thread pool practice

Source: Internet
Author: User

Android custom thread pool practice and android thread pool practice

In the previous article, we talked about the basic use of AsyncTask, AsyncTask encapsulation, AsyncTask serial/parallel thread queue, custom thread pool, and fast creation of thread pool.

If you are not familiar with the thread pool, you can first look at Android AsyncTask for in-depth understanding, simple encapsulation, task queue analysis, and custom thread pool.

 

Bytes -------------------------------------------------------------------------------------------------------

1. Introduction to Executor

After Java 5, concurrent programming introduced a bunch of new APIs for starting, scheduling, and managing threads. The Executor framework is introduced in Java 5 and uses the thread pool mechanism internally. util. in the cocurrent package, this framework is used to control the startup, execution, and shutdown of threads, which can simplify concurrent programming operations. Therefore, after Java 5, it is better to use Executor to start a Thread than to use the Thread start method, in addition to easier management and efficiency (implemented using a Thread pool to save costs, another key point is to help avoid this escape-if we start a thread in the constructor, because another task may be executed before the constructor ends, in this case, half of the objects initialized may be accessed and Executor will be used in the constructor.

Executor frameworks include: thread pool, Executor, Executors, ExecutorService, CompletionService, Future, and Callable.

In java code, Executor is an interface with only one method.

public interface Executor {    /**     * Executes the given command at some time in the future.  The command     * may execute in a new thread, in a pooled thread, or in the calling     * thread, at the discretion of the {@code Executor} implementation.     *     * @param command the runnable task     * @throws RejectedExecutionException if this task cannot be     * accepted for execution     * @throws NullPointerException if command is null     */    void execute(Runnable command);}

  

2. ExecutorService

ExecutorService is an interface that inherits Executor. In addition to the execute (Runnable command) method, It also expands other methods:

public interface ExecutorService extends Executor {}
  • void shutdown();
  • List<Runnable> shutdownNow();
  • boolean isShutdown();
  • boolean isTerminated();
  • boolean awaitTermination(long timeout, TimeUnit unit)
    throws InterruptedException;
  • <T> Future <T> submit (Callable <T> task); // submit a task
  • <T> Future <T> submit (Runnable task, T result); // submit a task
  • Future <?> Submit (Runnable task); // submit a task
  • <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
    throws InterruptedException;
  • <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
    long timeout, TimeUnit unit)
    throws InterruptedException;
  • <T> T invokeAny(Collection<? extends Callable<T>> tasks)
    throws InterruptedException, ExecutionException;
  • <T> T invokeAny(Collection<? extends Callable<T>> tasks,
    long timeout, TimeUnit unit)
    throws InterruptedException, ExecutionException, TimeoutException;
2.1 execute (Runnable)

Receives a java. lang. Runnable object as a parameter and executes it asynchronously. The following is an example of running Runnable using ExecutorService:

Package com. app; import java. util. concurrent. executorService; import java. util. concurrent. executors; public class ExecutorTest {public static void main (String [] args) {// create a thread pool with a fixed thread count of 10 ExecutorService executorService = Executors. newFixedThreadPool (10); // executes a task. The task is a new Runnable () object executorservice.exe cute (new Runnable () {@ Overridepublic void run () {Log. d (Thread. currentThread (). getName () ;}}); // close the thread pool executorService. shutdown ();}}

Result:

pool-1-thread-1

There is no way to obtain the result after running Runnable. If you want to obtain the returned value after running, you must use the execute () method that receives the Callable parameter, the latter will be mentioned below.

 

2.2, Submit (Runnable)

Method submit (Runnable) also receives a Runnable implementation as a parameter, but returns a Future object. This Future object can be used to determine whether Runnable is executed. The following is an example of the submit () method of ExecutorService:

Package com. app; import java. util. concurrent. executorService; import java. util. concurrent. executors; import java. util. concurrent. future; public class ExecutorTest {public static void main (String [] args) {// create a thread pool with a fixed thread count of 10 ExecutorService executorService = Executors. newFixedThreadPool (10); // execute a task. The task is a new Runnable () object Future future = executorService. submit (new Runnable () {@ Overridepublic void run () {Log. d (Thread. currentThread (). getName () ;}}); try {// if the task ends, nullLog is returned. d ("" + future. get ();} catch (Exception e) {e. printStackTrace ();} // close the thread pool executorService. shutdown ();}}

Result:

pool-1-thread-1
null

2.3 submit (Callable)

The method submit (Callable) is similar to the method submit (Runnable), but the difference is that they receive different parameter types. The Callable instance is similar to the Runnable instance, but the call () method of Callable can return one result. The method Runnable. run () cannot return results.

The return value of Callable can be obtained from the Future object returned by the method submit (Callable. The following is an example of ExecutorService Callable:

Package com. app; import java. util. concurrent. callable; import java. util. concurrent. executorService; import java. util. concurrent. executors; import java. util. concurrent. future; public class ExecutorTest {public static void main (String [] args) {// create a thread pool with a fixed thread count of 10 ExecutorService executorService = Executors. newFixedThreadPool (10); // execute a task. The task is a new Callable () object Future future = executorService. submit (new Callable <String> () {@ Overridepublic String call () throws Exception {return "executed ";}}); try {// if the task ends, Log is returned. d ("Result:" + future. get ();} catch (Exception e) {e. printStackTrace ();} // close the thread pool executorService. shutdown ();}}

Result:

The result is: the execution is complete.

 

2.4. inVokeAny ()

Method invokeAny () receives a set of Callable objects as parameters. Calling this method does not return the Future object, but returns the result of a Callable object in the Set, and cannot guarantee which Callable is returned after the call, it is only known that it is the Callable object of these Callable. If a task is completed or an exception is thrown, the method will cancel the execution of other Callable statements.

Package com. app; import java. util. arrayList; import java. util. list; import java. util. concurrent. callable; import java. util. concurrent. executionException; import java. util. concurrent. executorService; import java. util. concurrent. executors; public class ExecutorTest {public static void main (String [] args) {// create a thread pool with a fixed thread count of 10 ExecutorService executorService = Executors. newFixedThreadPool (10); List <Callable <String> list = new ArrayList <> (); // create the first CallableCallable <String> callable1 = new Callable <String> () {@ Overridepublic String call () throws Exception {Log. d ("callable 1 Thread is:" + Thread. currentThread (). getName (); return "callable 1 executed" ;}}; // create the second CallableCallable <String> callable2 = new Callable <String> () {@ Overridepublic String call () throws Exception {Log. d ("callable 2 Thread is:" + Thread. currentThread (). getName (); return "callable 2 executed" ;}}; list. add (callable1); list. add (callable2); try {String result = executorService. invokeAny (list); Log. d ("result:" + result);} catch (InterruptedException e1) {e1.printStackTrace ();} catch (ExecutionException e1) {e1.printStackTrace ();} // close the thread pool executorService. shutdown ();}}

Result:

Callable 1 thread is: pool-1-thread-1

Callable 2 thread: pool-1-thread-2
The result is: callable 2 is finished.

Summary:

1. You can see that the call methods in Callable are all run in sub-threads,

2. executorService. invokeAny (list); the return value is the return value of any Callable. Which one is possible.

 

2.5. invokeAll ()

The invokeAll () method calls all Callable objects in the parameter set and returns a set containing Future objects. You can use the returned set to manage the execution results of each Callable. Note that the task may end due to an exception, so it may not be running successfully. However, we cannot see this difference through the Future object.

Package com. app; import java. util. arrayList; import java. util. list; import java. util. concurrent. callable; import java. util. concurrent. executorService; import java. util. concurrent. executors; import java. util. concurrent. future; public class ExecutorTest {public static void main (String [] args) {// create a thread pool with a fixed thread count of 10 ExecutorService executorService = Executors. newFixedThreadPool (10); List <Callable <String> list = new ArrayList <> (); // create the first CallableCallable <String> callable1 = new Callable <String> () {@ Overridepublic String call () throws Exception {Log. d ("callable 1 Thread is:" + Thread. currentThread (). getName (); return "callable 1 executed" ;}}; // create the second CallableCallable <String> callable2 = new Callable <String> () {@ Overridepublic String call () throws Exception {Log. d ("callable 2 Thread is:" + Thread. currentThread (). getName (); return "callable 2 executed" ;}}; list. add (callable1); list. add (callable2); List <Future <String> result; try {result = executorService. invokeAll (list); for (Future <String> future: result) {Log. d ("Result:" + future. get () ;}} catch (Exception e) {e. printStackTrace ();} // close the thread pool executorService. shutdown ();}}

 Result

Callable 1 thread is: pool-1-thread-1
Callable 2 thread: pool-1-thread-2
The result is: callable 1 is finished.
The result is: callable 2 is finished.

Note: 1: The call methods of Callable are all executed in the sub-thread.

2: executorService. invokeAll (list) is the return value. However, it is returned only after all Callable objects are executed. The returned value is a list, with the same sequence as List <Callable>. If any Callable exception occurs during execution, the program will crash and no return value will be returned.

2.6 how to disable the ExecuteService?

When ExecutorService is used, we should disable it to ensure that the thread will not continue to run. For example, if your program is started using the main () method and the main thread exits your program, if you still have an active ExecutorService in your program, the program will continue to run. Active threads in ExecutorService will prevent the Java Virtual Machine from being shut down. 

To close the thread in ExecutorService, you need to call the shutdown () method. ExecutorService does not close immediately, but does not receive new tasks. Once all threads finish executing the current task, ExecutorServie will actually close. All tasks submitted to ExecutorService before calling the shutdown () method are executed.
If you want to immediately disable ExecutorService, you can call the shutdownNow () method. This method immediately closes all ongoing tasks and skips all submitted tasks that are not yet running. However, it cannot be guaranteed whether a running task can be successfully closed. It may be disabled or executed until the task ends. This is the best attempt.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.