Welcome to pay attention to my public Android program Yuan get more technical dry goods ~!

I received a bug in my work a few days ago, probably because there was an exception in the app running process, but I checked the APP log and system log, but no exception log was printed. Finally found the context. GetExternalCacheDir method return value is null, thought can bug back to man to fix the system group, under the guidance of leader, found problems in the app: The thread pool started the thread with the method of submit, but did not process the return value of Submit. There was no catch NPE in the running process, and the task kept circulating in the thread pool with errors, which led to the problem. Finally, the submit method of all thread pools was replaced with the execute method. When there is an uncaught execption, the system will crash directly and print logs in the system to facilitate subsequent bug handling.

Here’s the difference between Execute and Submit.

Submit:

public interface ExecutorService extends Executor {... <T>Future<T> submit(Callable<T> task); <T>Future<T> submit(Runnable task, T result); Future<? > submit(Runnable task); . }Copy the code

Submit is from the ExecutorService interface. As can be seen from the ExecutorService interface, there are three sumbit() methods, which can be Callable or Runnable, and which return value Future. (Note: A Callable, like a Runnable, is a way to create a thread by implementing its call() method, which can return a value and throw an exception.)

Execute: The execute method is derived from the Executor interface, from which the previous ExecutorService interface is inherited. Executor is the top layer, which contains only one execute() 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);
}
Copy the code

Conclusion: Submit accepts only Runnable and Callable tasks, but Runnable returns void. So the Future’s get() is still null

Submit () returns a value, but execute() does not. For example, if you have a task and want it to tell me whether it succeeded or failed, and then proceed with the following operation, submit is required

For example, submit is used when a task throws checked or unchecked exceptions, and you want external callers to perceive these exceptions and act in a timely manner. Throw an exception by catching it on Future.get() and then processing it.