简单解析execute和submit有什么区别

1、execute 方法位于 java.util.concurrent.Executor 中

void execute(Runnable command);

2、execute 的具体实现

public void execute(Runnable command) {
    if (command == null)
      throw new NullPointerException();
    /*
     * Proceed in 3 steps:
     *
     * 1. If fewer than corePoolSize threads are running, try to
     * start a new thread with the given command as its first
     * task. The call to addWorker atomically checks runState and
     * workerCount, and so prevents false alarms that would add
     * threads when it shouldn't, by returning false.
     *
     * 2. If a task can be successfully queued, then we still need
     * to double-check whether we should have added a thread
     * (because existing ones died since last checking) or that
     * the pool shut down since entry into this method. So we
     * recheck state and if necessary roll back the enqueuing if
     * stopped, or start a new thread if there are none.
     *
     * 3. If we cannot queue task, then we try to add a new
     * thread. If it fails, we know we are shut down or saturated
     * and so reject the task.
     */
    int c = ctl.get();
    if (workerCountOf(c) < corePoolSize) {
      if (addWorker(command, true))
        return;
      c = ctl.get();
    }
    if (isRunning(c) && workQueue.offer(command)) {
      int recheck = ctl.get();
      if (! isRunning(recheck) && remove(command))
        reject(command);
      else if (workerCountOf(recheck) == 0)
        addWorker(null, false);
    }
    else if (!addWorker(command, false))
      reject(command);
  }

3、submit 方法位于 java.util.concurrent.AbstractExecutorService 中

/**
   * @throws RejectedExecutionException {@inheritDoc}
   * @throws NullPointerException    {@inheritDoc}
   */
  public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
  }

  /**
   * @throws RejectedExecutionException {@inheritDoc}
   * @throws NullPointerException    {@inheritDoc}
   */
  public <T> Future<T> submit(Runnable task, T result) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task, result);
    execute(ftask);
    return ftask;
  }

  /**
   * @throws RejectedExecutionException {@inheritDoc}
   * @throws NullPointerException    {@inheritDoc}
   */
  public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
  }

4、submit 方式使用 Runnable 入参时的具体实现

static final class RunnableAdapter<T> implements Callable<T> {
    final Runnable task;
    final T result;
    RunnableAdapter(Runnable task, T result) {
      this.task = task;
      this.result = result;
    }
    public T call() {
      task.run();
      return result;
    }
  }

5、submit 方式使用 Callable 入参时的具体实现

public FutureTask(Callable<V> callable) {
    if (callable == null)
      throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;    // ensure visibility of callable
  }

  //重写run方法
  public void run() {
    if (state != NEW ||
      !UNSAFE.compareAndSwapObject(this, runnerOffset,
                     null, Thread.currentThread()))
      return;
    try {
      Callable<V> c = callable;
      if (c != null && state == NEW) {
        V result;
        boolean ran;
        try {
          result = c.call();
          ran = true;
        } catch (Throwable ex) {
          result = null;
          ran = false;
          setException(ex);
        }
        if (ran)
          set(result);
      }
    } finally {
      // runner must be non-null until state is settled to
      // prevent concurrent calls to run()
      runner = null;
      // state must be re-read after nulling runner to prevent
      // leaked interrupts
      int s = state;
      if (s >= INTERRUPTING)
        handlePossibleCancellationInterrupt(s);
    }
  }

总结:

1、根据源码可以看到 execute 仅可以接受Runnable类型,而 submit 重载了三个方法,参数可以是 Runnable 类型、Runnable 类型+泛型T 、Callable 类型接口。

2、从上面源码可以看出 submit 方法实际上如果用Runnable类型的接口可以有返回值,也可以没有返回值。

3、传递Runnable类型接口加泛型T会被进一步封装,在 Executors 这个类里面有个内部类 RunnableAdapter 实现了 Callable 接口。

4、看submit方法可以看出,submit最终也是在调用 execute 方法,无论是 Runnable 还是 Callable 类型接口,都会被封装成 FutureTask 继续执行。

5、如果使用submit方法提交,会进一步封装成FutureTask,执行execute方法,在FutureTask里面重写的run方法里面调用 Callable 接口的call方法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 通过代码示例了解submit与execute的区别

    (1)可以接受的任务类型 submit: execute: 可以看出: execute只能接受Runnable类型的任务 submit不管是Runnable还是Callable类型的任务都可以接受,但是Runnable返回值均为void,所以使用Future的get()获得的还是null (2)返回值 由Callable和Runnable的区别可知: execute没有返回值 submit有返回值,所以需要返回值的时候必须使用submit (3)异常 1.execute中抛出异常 execute

  • JDBC Oracle执行executeUpdate卡死问题的解决方案

    使用jdbc执行oracle的删除操作的时候程序卡死不动了. 问题分析: 对于这一类问题,一般都是数据库事务未提交,导致executeUpdate卡死. 所以解决方案: 1.在执行完executeUpdate 后,记得将事务提交con.commit(); 2.找到数据库客户端,执行commit操作. 如果以上操作还不行. 那么应该是数据库在执行 数据操作失败 or 事务未提交 之后 将需要执行的sql语句锁死了 Oracle的操作方式: 先查询锁定记录 : SELECT s.sid, s.ser

  • PHP PDOStatement::execute讲解

    PDOStatement::execute PDOStatement::execute - 执行一条预处理语句(PHP 5 >= 5.1.0, PECL pdo >= 0.1.0) 说明 语法 bool PDOStatement::execute ([ array $input_parameters ] ) 执行预处理过的语句.如果预处理过的语句含有参数标记,必须选择下面其中一种做法: 调用PDOStatement::bindParam()绑定 PHP 变量到参数标记:如果有的话,通过关联参数

  • Failed to execute goal org...的解决办法

    背景:本项目使用JDK1.8 编译maven工程的时候出现如下错误: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1 pom中如下配置maven插件,配置中声明使用JDK1.8: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</

  • ThreadPoolExecutor线程池原理及其execute方法(详解)

    jdk1.7.0_79 对于线程池大部分人可能会用,也知道为什么用.无非就是任务需要异步执行,再者就是线程需要统一管理起来.对于从线程池中获取线程,大部分人可能只知道,我现在需要一个线程来执行一个任务,那我就把任务丢到线程池里,线程池里有空闲的线程就执行,没有空闲的线程就等待.实际上对于线程池的执行原理远远不止这么简单. 在Java并发包中提供了线程池类--ThreadPoolExecutor,实际上更多的我们可能用到的是Executors工厂类为我们提供的线程池:newFixedThreadP

  • MySQL中预处理语句prepare、execute与deallocate的使用教程

    前言 MySQL官方将prepare.execute.deallocate统称为PREPARE STATEMENT,我习惯称其为[预处理语句],其用法十分简单,下面话不多说,来一起看看详细的介绍吧. 示例代码 PREPARE stmt_name FROM preparable_stmt EXECUTE stmt_name [USING @var_name [, @var_name] ...] - {DEALLOCATE | DROP} PREPARE stmt_name 举个栗子: mysql>

  • python executemany的使用及注意事项

    使用executemany对数据进行批量插入的话,要注意一下事项: #coding:utf8 conn = MySQLdb.connect(host = "localhost", user = "root", passwd = "123456", db = "myDB") cursor = conn.cursor() sql = "insert into myTable (created_day,name,count

  • MySQL execute、executeUpdate、executeQuery三者的区别

    execute.executeUpdate.executeQuery三者的区别(及返回值) 一.boolean execute(String sql) 允许执行查询语句.更新语句.DDL语句. 返回值为true时,表示执行的是查询语句,可以通过getResultSet方法获取结果:返回值为false时,执行的是更新语句或DDL语句,getUpdateCount方法获取更新的记录数量. 例子: public static void main(String[] args) { Connection

  • 简单解析execute和submit有什么区别

    1.execute 方法位于 java.util.concurrent.Executor 中 void execute(Runnable command); 2.execute 的具体实现 public void execute(Runnable command) { if (command == null) throw new NullPointerException(); /* * Proceed in 3 steps: * * 1. If fewer than corePoolSize t

  • 线程池中execute与submit的区别说明

    目录 线程池execute与submit区别 execute submit 例1 例2 线程池submit和execute方法原理 线程池的作用 线程池的原理 线程池execute与submit区别 在使用线程池的时候,看到execute()与submit()方法.都可以使用线程池执行一个任务,但是两者有什么区别呢? execute void execute(Runnable command); submit <T> Future<T> submit(Callable<T&g

  • java简单解析xls文件的方法示例【读取和写入】

    本文实例讲述了java简单解析xls文件的方法.分享给大家供大家参考,具体如下: 读取: import java.io.*; import jxl.*; import jxl.write.*; import jxl.format.*; class Aa{ public static void main(String args[]) { try{ Workbook workbook = null; try { workbook = Workbook.getWorkbook(new File("d:

  • java实现简单解析XML文件功能示例

    本文实例讲述了java实现简单解析XML文件功能.分享给大家供大家参考,具体如下: package demo; import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException;

  • 基于js粘贴事件paste简单解析以及遇到的坑

    在用户执行粘贴操作的时候,js能够获得剪切板的内容,本文讨论一下这个问题. 目前只有Chrome支持获取剪切板中的图片数据.还好需要这个功能的产品目前只支持Chrome和Safari,一些Chrome的新特性是可以尽情使用了,还是能够覆盖到大部分用户的.所以本文只讨论Chrome如何使用和如何阻止Safari,原理大概了解了,再研究其他浏览器相关的问题就容易多了. paste事件 可以用js给页面中的元素绑定paste事件的方法,当用户鼠标在该元素上或者该元素处于focus状态,绑定到paste

  • APS.NET MVC4生成二维码简单解析

    一.视图 @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <script src="~/Scripts/jquery-1.8.2.min.js"></scri

  • php简单解析mysqli查询结果的方法(2种方法)

    本文实例讲述了php简单解析mysqli查询结果的方法.分享给大家供大家参考,具体如下: 可将查询结果放入对象或数组中: 1. 将查询结果放入对象: $sql="select name,brief from cars"; $result=mysqli->query($sql); while($row=$result->fetch_object()) { echo $row->name; echo $row->brief; } 2. 放入数组: $sql=&quo

  • javascript闭包概念简单解析(推荐)

    关于"闭包"这个概念的文章在网上铺天盖地,基本已经稀烂了,但是有时候总感觉读了这么多的文章还是云山雾罩,当然是由于它本身就比较难于理解和涉及的知识较多,还有一个很重要的原因就是网上很多教程介绍可能存在一定的误区,或者说侧重点不同,下面就通过代码实例简单的介绍一下什么是闭包. 代码实例一: function a(){ var webName="我们"; console.log(webName); } a() 以上是一段非常简单的代码,当函数执行结束之后,它就会从内存中

  • js表单提交和submit提交的区别实例分析

    本文实例分析了js表单提交和submit提交的区别.分享给大家供大家参考,具体如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <

  • 简单谈谈SpringMVC转发和重定向的区别

    在servlet中,转发和重定向是由request和response完成的.两者之间的区别请看我之前的文章.那么在springMVC中是如何完成的呢? /**转发**/ @RequestMapping("/login.do") public String login(HttpServletRequest request,HttpServletResponse response){ request.setAttribute("message", "hello

随机推荐