zoukankan      html  css  js  c++  java
  • 线程池提交任务的两种方式:execute与submit的区别

    Java中的线程池在进行任务提交时,有两种方式:execute和submit方法。

    一、execute和submit的区别

    • execute只能提交Runnable类型的任务,无返回值。submit既可以提交Runnable类型的任务,也可以提交Callable类型的任务,会有一个类型为Future的返回值,但当任务类型为Runnable时,返回值为null。
    • execute在执行任务时,如果遇到异常会直接抛出,而submit不会直接抛出,只有在使用Future的get方法获取返回值时,才会抛出异常。

    测试代码:

    package com.javaBase.LineDistancePond;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * 〈一句话功能简述〉;
     * 〈execute与submit的区别〉
     *
     * @author jxx
     * @see [相关类/方法](可选)
     * @since [产品/模块版本] (可选)
     */
    public class TestThreadPoolBegin {
    
        public static void main(String[] args) throws Exception{
            ExecutorService es = Executors.newSingleThreadExecutor();
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println("Runnable线程处理开始...");
                    int a = 0;
                    int b = 3;
                    System.out.println("除以0的结果为:" + b/a);
                    System.out.println("Runnable线程处理结束...");
                }
            };
            es.execute(runnable);
            es.shutdown();
        }
    }

    执行结果:

    Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero
    Runnable线程处理开始...
        at com.javaBase.LineDistancePond.TestThreadPoolBegin$1.run(TestThreadPoolBegin.java:24)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
    
    Process finished with exit code 0
    package com.javaBase.LineDistancePond;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * 〈一句话功能简述〉;
     * 〈execute与submit的区别〉
     *
     * @author jxx
     * @see [相关类/方法](可选)
     * @since [产品/模块版本] (可选)
     */
    public class TestThreadPoolBegin {
    
        public static void main(String[] args) throws Exception{
            ExecutorService es = Executors.newSingleThreadExecutor();
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println("Runnable线程处理开始...");
                    int a = 0;
                    int b = 3;
                    System.out.println("除以0的结果为:" + b/a);
                    System.out.println("Runnable线程处理结束...");
                }
            };
            es.submit(runnable);
            es.shutdown();
        }
    }

    执行结果:

    Runnable线程处理开始...
    
    Process finished with exit code 0
    package com.javaBase.LineDistancePond;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    /**
     * 〈一句话功能简述〉;
     * 〈execute与submit的区别〉
     *
     * @author jxx
     * @see [相关类/方法](可选)
     * @since [产品/模块版本] (可选)
     */
    public class TestThreadPoolBegin {
    
        public static void main(String[] args) throws Exception{
            ExecutorService es = Executors.newSingleThreadExecutor();
            Callable callable = new Callable() {
                @Override
                public Object call() throws Exception {
                    System.out.println("线程处理开始...");
                    int a = 0;
                    int b = 3;
                    System.out.println("除以0的结果为:" + b/a);
                    System.out.println("线程处理结束...");
                    return "0";
                }
            };
            Future<String> future = es.submit(callable);
            System.out.println("任务执行完成,结果为:" + future.get());
        }
    }

    执行结果:

    Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:192)
        at com.javaBase.LineDistancePond.TestThreadPoolBegin.main(TestThreadPoolBegin.java:32)
    Caused by: java.lang.ArithmeticException: / by zero
        at com.javaBase.LineDistancePond.TestThreadPoolBegin$1.call(TestThreadPoolBegin.java:26)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
    线程处理开始...

    二、submit的get方法

      future的get方法在未获得返回值之前会一直阻塞,我们可以使用future的isDone方法判断任务是否执行完成,然后再决定是否get,因此上述代码我们可以优化如下:

    package com.javaBase.LineDistancePond;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    /**
     * 〈一句话功能简述〉;
     * 〈execute与submit的区别〉
     *
     * @author jxx
     * @see [相关类/方法](可选)
     * @since [产品/模块版本] (可选)
     */
    public class TestThreadPoolBegin {
    
        public static void main(String[] args) throws Exception{
            ExecutorService es = Executors.newSingleThreadExecutor();
            Callable callable = new Callable() {
                @Override
                public String call() throws Exception {
                    System.out.println("线程处理开始...");
                    int a = 2;
                    int b = 3;
                    System.out.println("3/2的结果为:" + b/a);
                    System.out.println("线程处理结束...");
                    return "0";
                }
            };
            Future<String> future = es.submit(callable);
            while(true) {
                //idDone:如果任务已完成,则返回 true。 可能由于正常终止、异常或取消而完成,在所有这些情况中,此方法都将返回 true。
                if(future.isDone()) {
                    System.out.println("任务执行完成:" + future.get());
                    break;
                }
            }
            es.shutdown();
        }
    }

    执行结果:

    线程处理开始...
    3/2的结果为:1
    线程处理结束...
    线程执行完成:0
    
    Process finished with exit code 1
  • 相关阅读:
    第6月第4天 AVMutableComposition AVMutableVideoComposition
    error: WatchKit App doesn't contain any WatchKit Extensions whose WKAppBundleIdentifier matches
    领导力和管理的区别是什么?
    小企业如何做好员工管理?
    市场营销案例书籍,市场营销必看的书籍推荐
    情商书籍排行榜:这6本书让你更好地做自己
    市场营销原理,看完这本书你才能懂什么叫市场营销
    能帮你提高情商的书籍推荐
    销售人员最该看的书:《销售管理必读12篇》
    适合初学者看的管理类书籍推荐
  • 原文地址:https://www.cnblogs.com/jxxblogs/p/11882381.html
Copyright © 2011-2022 走看看