三个区别:
1、接收的参数不一样
2、submit有返回值,而execute没有
Method submit extends base method Executor.execute by creating and returning a Future that can be used to cancel execution and/or wait for completion.
用到返回值的例子,比如说我有很多个做validation的task,我希望所有的task执行完,然后每个task告诉我它的执行结果,是成功还是失败,如果是失败,原因是什么。然后我就可以把所有失败的原因综合起来发给调用者。
个人觉得cancel execution这个用处不大,很少有需要去取消执行的。
而最大的用处应该是第二点。
3、submit方便Exception处理
There is a difference when looking at exception handling. If your tasks throws an exception and if it was submitted with execute
this exception will go to the uncaught exception handler (when you don't have provided one explicitly, the default one will just print the stack trace to System.err
). If you submitted the task with submit
any thrown exception, checked or not, is then part of the task's return status. For a task that was submitted with submit
and that terminates with an exception, the Future.get
will rethrow this exception, wrapped in an ExecutionException
.
意思就是如果你在你的task里会抛出checked或者unchecked exception,而你又希望外面的调用者能够感知这些exception并做出及时的处理,那么就需要用到submit,通过捕获Future.get抛出的异常。
比如说,我有很多更新各种数据的task,我希望如果其中一个task失败,其它的task就不需要执行了。那我就需要catch Future.get抛出的异常,然后终止其它task的执行,代码如下:
import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class ExecutorServiceTest { public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); List<Future<String>> resultList = new ArrayList<Future<String>>(); // 创建10个任务并执行 for (int i = 0; i < 10; i++) { // 使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中 Future<String> future = executorService.submit(new TaskWithResult(i)); // 将任务执行结果存储到List中 resultList.add(future); } executorService.shutdown(); // 遍历任务的结果 for (Future<String> fs : resultList) { try { System.out.println(fs.get()); // 打印各个线程(任务)执行的结果 } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { executorService.shutdownNow(); e.printStackTrace(); return; } } } } class TaskWithResult implements Callable<String> { private int id; public TaskWithResult(int id) { this.id = id; } /** * 任务的具体过程,一旦任务传给ExecutorService的submit方法,则该方法自动在一个线程上执行。 * * @return * @throws Exception */ public String call() throws Exception { System.out.println("call()方法被自动调用,干活!!! " + Thread.currentThread().getName()); if (new Random().nextBoolean()) throw new TaskException("Meet error in task." + Thread.currentThread().getName()); // 一个模拟耗时的操作 for (int i = 999999999; i > 0; i--) ; return "call()方法被自动调用,任务的结果是:" + id + " " + Thread.currentThread().getName(); } } class TaskException extends Exception { public TaskException(String message) { super(message); } }
Future.get()方法默认是等待线程执行结束,如果插入参数Future.get(10, TimeUnit.MILLISECONDS),则返回等待10毫秒后的状态(最多等待10毫秒)。
相关推荐
然而,在使用java线程池时,一个常见的问题是:使用完线程池后到底要不要关闭?本文将通过实例代码和详细解释,告诉大家使用完线程池后一定要关闭,否则可能会导致内存泄露和应用崩溃。 首先,让我们了解一下java...
以下示例显示如何使用线程池。首先创建 ManualResetEvent 对象,此对象使程序能够知道线程池何时运行完所有的工作项。接着,尝试向线程池添加一个线程。如果添加成功,则添加其余的线程(本例中为 4 个)。然后...
线程池在Android开发中是不可或缺的一部分,尤其是在处理耗时操作如网络请求、数据库操作时,合理使用线程池能有效提升应用性能和用户体验。本文将通过一个简单的Demo,介绍如何在Android中使用线程池。 一、线程池...
总结,C#线程池是多线程编程中不可或缺的一部分,它通过智能管理线程,提高了程序的运行效率。了解并熟练掌握线程池的使用,有助于我们在实际开发中编写出更高效、更稳定的代码。在VS2013控制台窗口中实践线程池的...
封装线程池时,建议创建一个工具类或单例模式的类,提供简单的接口供其他组件调用,如`execute(Runnable task)`、`submit(Callable<T> task)`等,以降低使用难度。 在实际开发中,线程池的封装和使用能够帮助我们更...
例如,在代码示例中,使用Executors.newSingleThreadExecutor()创建了一个单线程线程池,并且通过pool.execute(t1);等方法提交了多个任务到线程池中执行。最后,通过调用pool.shutdown()方法来关闭线程池,释放相关...
线程池是多线程编程中的一个重要概念,它是一种线程使用模式,通过预先创建一组线程并维护一个线程集合来处理并发任务。在Windows操作系统中,内建的线程池API(Thread Pool API)提供了高效且灵活的线程管理机制,...
线程池是一组等待使用的线程集合。当任务需要执行时,线程池会从池中分配一个线程来执行任务,而不是每次都创建新的线程。任务完成后,线程并不立即销毁,而是返回线程池等待下一个任务。这种机制可以减少系统资源的...
在Android应用开发中,线程池的使用是提高性能和优化资源管理的重要手段。线程池允许我们预先创建一定数量的线程,处理并发任务,而不是每次需要时都创建新线程,这样可以减少系统资源的消耗,提高响应速度。本示例...
3. **优先级调度**:虽然线程池本身并不支持优先级调度,但在.NET Framework 4.5及以上版本中,你可以使用`Task`类配合`TaskCreationOptions.LongRunning`选项创建长时间运行的任务,这将提示线程池创建一个新线程来...
总结,C#线程池的高级应用涉及到线程的创建、调度、监控以及与异步I/O的结合使用。通过合理利用线程池,开发者可以构建高效、稳定的多线程应用程序。在实际开发中,应结合项目需求和系统资源,灵活运用线程池的各种...
为了简化线程池的配置和使用,`Executors`类提供了一系列静态工厂方法来创建常用的线程池。 - **newSingleThreadExecutor**:创建一个只包含一个线程的线程池。适用于需要保证任务顺序执行的场景,例如执行一系列...
1. **线程池核心概念**: - **线程池(ThreadPool)**:是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池中的线程可以被重复利用,减少了创建和销毁线程的开销。 - *...
阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池...
总结来说,"火山安卓编程线程池例子"是一个关于Android应用开发中利用火山编程框架进行多线程管理和优化的实践案例。通过对这个例子的学习,开发者能够深入理解线程池的工作原理和优势,提升其在Android并发编程中的...
本文介绍的线程池采用C++语言,在windows平台下实现。 适用场合: 1.需要大量的线程来完成任务,且完成任务的时间比较短。 2.对性能要求苛刻的应用,比如要求服务器迅速相应客户请求。 3.接受突发性的大量请求...
线程池是Java并发编程中的重要概念,它是一种线程使用模式,用于高效地管理和执行大量并发任务。在Java中,我们主要通过`java.util.concurrent`包中的`ExecutorService`接口及其实现类来创建和管理线程池。线程池的...
4. **创建线程池**:使用`Executors`类的静态方法创建线程池,例如 `newFixedThreadPool(int nThreads)` 创建一个固定大小的线程池,其中线程数量是可预设的。 5. **使用线程池**: - **创建线程池对象**:如 `...
总结,Quartz 线程池是实现高效、可靠任务调度的关键组件。理解其工作原理并合理配置,能够帮助我们更好地利用系统资源,提升应用的响应速度和稳定性。在开发过程中,对线程池的监控和优化是确保系统性能的重要环节...
线程池是一种线程使用模式,它预先创建了一组线程,当有任务需要执行时,线程池会分配一个空闲线程来执行任务,任务完成后,线程返回线程池等待下一次分配。这种方式提高了系统资源的利用率,减少了线程创建和销毁的...