多线程之execute,submit

来源:互联网 发布:基于of数据库管理系统 编辑:程序博客网 时间:2024/06/01 21:42

execute

execute() 是在Executor接口中定义的,ThreadPoolExecutor继承了AbstractExecutorService抽象类,该抽象类实现了ExecutorService接口(但并没有覆盖execute方法),而ExecutorService接口继承了Executor接口。简而言之就是说ThreadPoolExecutor实现了execute()方法。

  • awaitTermination(long timeout, TimeUnit unit)方法
private static void excuteTest1() {        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);        executorService.execute(() -> {            try {                TimeUnit.SECONDS.sleep(10);            } catch (Exception e) {                System.out.println("线程内部中断异常 "+ e);            }        });        executorService.shutdown();        try {            executorService.awaitTermination(2,TimeUnit.SECONDS);        } catch (InterruptedException e) {            System.out.println("awaitTermination InterruptedException异常 "+ e);        } catch (Exception e) {            System.out.println("awaitTermination Exception "+ e);        }    }

总结:awaitTermination最大等待时间,等待线程shutdown(),所以一定要先用shutdown()方法,在等待过程中,可被打断。当awaitTermination的最大等待时间到了,除了继续执行下面代码,不会有其它任何功能。


  • execute内的线程异常
private static void excuteTest1() {        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);        executorService.execute(() -> {            try {                TimeUnit.SECONDS.sleep(10);            } catch (Exception e) {                System.out.println("线程内部中断异常 " + e);            }            System.out.println("没有异常线程执行完毕");        });        try {            executorService.execute(() -> {                int i = 2 / 0;            });        } catch (Exception e) {            System.out.println("execute()异常Exception " + e);        }        executorService.shutdown();    }

总结:从结果可以看出,当execute内的线程发生异常时,execute方法是无法捕获的,直接可以在控制台看到异常信息,并且不影响其它线程。




submit

submit方法是ExecutorService接口里面定义的,具体的实现由AbstractExecutorService进行。
submit方法被重载了三次,分别对用三个不同的参数。对api摘录如下:

submit public Future<?> submit(Runnable task)提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在成功 完成时将会返回null。submit public Future submit(Runnable task,T result) 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在成功完成时将会返回给定的结果result。submit public Future submit(Callable task) 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。该 Future 的 get 方法在成功完成时将会返回该任务的结果。 如果想立即阻塞任务的等待,则可以使用 result = exec.submit(aCallable).get(); 形式的构造。注:Executors 类包括了一组方法,可以转换某些其他常见的类似于闭包的对象,例如,将 PrivilegedAction 转换为Callable 形式,这样就可以提交它们了。

  • get()
private static void futureTest1() {        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);        System.out.println(System.currentTimeMillis());        Future<String> future = executorService.submit(() -> {            try {                TimeUnit.SECONDS.sleep(10);            } catch (Exception e) {                e.printStackTrace();            }            return "sss";        });        System.out.println(System.currentTimeMillis());        try {            final String result = future.get();            System.out.println("得到返回结果"+result);        } catch (InterruptedException e) {            System.err.println("get InterruptedException" + e);        } catch (ExecutionException e) {            System.err.println("get ExecutionException" + e);        } catch (Exception e) {            System.err.println("get Exception" + e);        }        executorService.shutdown();    }

总结:get()方法会一直阻塞,直到拿到返回结果。get()会抛出InterruptedException 和ExecutionException。


  • get(long timeout, TimeUnit unit)
private static void futureTest1() {        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);        Future<String> future = executorService.submit(() -> {            try {                TimeUnit.SECONDS.sleep(10);            } catch (Exception e) {                System.out.println("线程内部异常" + e);            }            System.out.println("线程快要返回结果");            return "sss";        });        try {            final String result = future.get(2, TimeUnit.SECONDS);            System.out.println("得到返回结果" + result);        } catch (InterruptedException e) {            System.err.println("get InterruptedException" + e);        } catch (ExecutionException e) {            System.err.println("get ExecutionException" + e);        } catch (TimeoutException e) {            System.err.println("get TimeoutException" + e);        } catch (Exception e) {            System.err.println("get Exception" + e);        }        executorService.shutdown();    }

总结:超时后会抛出超时异常,对线程池中线程无任何影响。


  • submit提交的线程发生异常
private static void futureTest1() {        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);        Future<String> future = null;        try {            future = executorService.submit(() -> {                try {                    TimeUnit.SECONDS.sleep(10);                } catch (Exception e) {                    System.out.println("线程内部异常" + e);                }                int i = 2 / 0;                return "sss";            });        } catch (Exception e) {            System.err.println("submit Exception" + e);        }        try {            final String result = future.get(100, TimeUnit.SECONDS);            System.out.println("得到返回结果" + result);        } catch (InterruptedException e) {            System.err.println("get InterruptedException" + e);        } catch (ExecutionException e) {            System.err.println("get ExecutionException" + e);        } catch (TimeoutException e) {            System.err.println("get TimeoutException" + e);        } catch (Exception e) {            System.err.println("get Exception" + e);        }        executorService.shutdown();    }

总结:异常在会get()的ExecutionException 捕获。


  • cancel(true):
private static void futureTest1() {        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);        Future<String> future = null;        try {            future = executorService.submit(() -> {                while (!Thread.currentThread().isInterrupted()){                    System.out.println("=++++++=");                }                return "sss";            });        } catch (Exception e) {            System.err.println("submit Exception" + e);        }        try {            TimeUnit.MILLISECONDS.sleep(3);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(future.cancel(true));        System.out.println(future.isCancelled());        executorService.shutdown();    }

总结:cancel(true)调用interrupt试图去中断线程。


  • isDone()
  /**     * Returns {@code true} if this task completed.     *     * Completion may be due to normal termination, an exception, or     * cancellation -- in all of these cases, this method will return     * {@code true}.     *     * @return {@code true} if this task completed     */    boolean isDone();



execute和submit区别

  1. 方法execute没有返回值,submit有返回值。
  2. 这里写图片描述

  3. 如果不需要返回值,使用execute,效率更高。

原创粉丝点击