当前位置:实例文章 » JAVA Web实例» [文章]线程池学习(二)execute() 和 submit() 的区别

线程池学习(二)execute() 和 submit() 的区别

发布人:shili8 发布时间:2025-01-11 22:25 阅读次数:0

**线程池学习(二)**

在上一篇文章中,我们已经了解了线程池的基本概念、创建线程池的方法以及线程池的使用。今天我们将继续讨论线程池中的两个重要方法:`execute()` 和 `submit()`. 这两个方法都是用于执行任务的,但它们有着不同的设计理念和使用场景。

### execute()

`execute()` 方法是线程池中最早出现的一个方法,它用于直接执行一个Runnable或Callable对象。这个方法非常简单,仅仅是将任务放入到线程池中,然后由线程池内部的线程来执行。

javapublic void execute(Runnable command) {
 if (command == null)
 throw new NullPointerException();
 // 将任务放入到线程池中 addTask(command);
}


在上面的代码中,我们可以看到`execute()`方法首先检查传入的Runnable或Callable对象是否为null,如果是则抛出一个NullPointerException. 然后,它将任务放入到线程池中,具体来说就是调用了`addTask()`方法。

### submit()

`submit()` 方法也是用于执行一个Runnable或Callable对象,但它比 `execute()` 方法更强大。这个方法不仅可以直接执行任务,还可以返回一个Future对象,这个Future对象代表了任务的执行结果。

javapublic Future submit(Runnable task) {
 if (task == null) throw new NullPointerException();
 // 将任务放入到线程池中 RunnableInfo r = SynchronousQueue.enqueue(task);
 int c = availableProcessors();
 for (int i =0; i < Math.min(c, _common.poolSize); i++)
 internalAdd(r);
 return r;
}

public  Future submit(Callable task) {
 if (task == null) throw new NullPointerException();
 // 将任务放入到线程池中 RunnableFuture f = SynchronousQueue.enqueue(task);
 int c = availableProcessors();
 for (int i =0; i < Math.min(c, _common.poolSize); i++)
 internalAdd(f);
 return f;
}


在上面的代码中,我们可以看到`submit()`方法有两个重载版本,一个用于Runnable对象,另一个用于Callable对象。无论哪种情况,它们都会将任务放入到线程池中,然后返回一个Future对象。

### execute() 和 submit() 的区别虽然 `execute()` 和 `submit()` 都是用于执行任务的,但它们有着不同的设计理念和使用场景。

* `execute()` 方法直接执行一个Runnable或Callable对象,而不返回任何结果。
* `submit()` 方法不仅可以直接执行任务,还可以返回一个Future对象,这个Future对象代表了任务的执行结果。

在大多数情况下,`submit()` 方法比 `execute()` 方法更合适,因为它提供了更多的灵活性和控制权。然而,在某些特定场景中,`execute()` 方法可能是更好的选择。

### 总结线程池中的 `execute()` 和 `submit()` 方法都是用于执行任务的,但它们有着不同的设计理念和使用场景。`execute()` 方法直接执行一个Runnable或Callable对象,而不返回任何结果。`submit()` 方法不仅可以直接执行任务,还可以返回一个Future对象,这个Future对象代表了任务的执行结果。在大多数情况下,`submit()` 方法比 `execute()` 方法更合适,因为它提供了更多的灵活性和控制权。

### 示例代码
javaimport java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {
 public static void main(String[] args) {
 // 创建一个线程池 ExecutorService executor = Executors.newFixedThreadPool(5);

 // 使用execute()方法执行任务 Runnable task1 = new Task("Task1");
 executor.execute(task1);

 // 使用submit()方法执行任务并获取Future对象 Runnable task2 = new Task("Task2");
 Future future = executor.submit(task2);
 try {
 System.out.println(future.get());
 } catch (Exception e) {
 e.printStackTrace();
 }

 // 关闭线程池 executor.shutdown();
 }
}

class Task implements Runnable {
 private String name;

 public Task(String name) {
 this.name = name;
 }

 @Override public void run() {
 System.out.println("Executing task: " + name);
 }
}


在上面的示例代码中,我们创建了一个线程池,然后使用 `execute()` 方法执行一个任务。接着,我们使用 `submit()` 方法执行另一个任务,并获取Future对象。最后,我们关闭线程池。

### 注释* 在这个示例代码中,我们使用了`Executors.newFixedThreadPool(5)`方法创建了一个固定大小的线程池,大小为5。
* 我们使用`executor.execute(task1)`方法执行第一个任务,然后使用`executor.submit(task2)`方法执行第二个任务,并获取Future对象。
* 最后,我们关闭线程池以释放系统资源。

这个示例代码演示了如何使用 `execute()` 和 `submit()` 方法执行任务,以及如何获取Future对象来代表任务的执行结果。

相关标签:学习java开发语言
其他信息

其他资源

Top