多线程之execute,submit

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,效率更高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值