zoukankan      html  css  js  c++  java
  • Java 线程池submit和execute

    submit方法:

    public abstract class AbstractExecutorService implements ExecutorService {
        
        protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
            return new FutureTask<T>(runnable, value);
        }
    
        protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
            return new FutureTask<T>(callable);
        }
    
        public Future<?> submit(Runnable task) {
            if (task == null) throw new NullPointerException();
            RunnableFuture<Void> ftask = newTaskFor(task, null);
            execute(ftask);
            return ftask;
        }
    
        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;
        }
    
        public <T> Future<T> submit(Callable<T> task) {
            if (task == null) throw new NullPointerException();
            RunnableFuture<T> ftask = newTaskFor(task);
            execute(ftask);
            return ftask;
        }
       //....
    }
    public interface RunnableFuture<V> extends Runnable, Future<V> {
        /**
         * Sets this Future to the result of its computation
         * unless it has been cancelled.
         */
        void run();
    }
       protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
                return new FutureTask<T>(runnable, value);
            }
            
            protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
                return new FutureTask<T>(callable);
            }
    public class FutureTask<V> implements RunnableFuture<V> {
    
        private final java.util.concurrent.FutureTask.Sync sync;
    
        public FutureTask(Callable<V> callable) {
            if (callable == null)
                throw new NullPointerException();
            sync = new java.util.concurrent.FutureTask.Sync(callable);
        }
    
        public FutureTask(Runnable runnable, V result) {
            sync = new java.util.concurrent.FutureTask.Sync(Executors.callable(runnable, result));
        }
        //....
    }

    submit返回的最终是FutureTask对象

    execute方法:

    public interface Executor {
        
        void execute(Runnable command);
    }

    具体的实现在ThreadPoolExecutor类中

        public void execute(Runnable command) {
            if (command == null)
                throw new NullPointerException();
     
            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);
        }

    submit内部调用execute

    submit有返回值

    submit方便exception处理

    submit的demo:

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    public class Main {
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newCachedThreadPool();
            List<Future<String>> resultList = new ArrayList<Future<String>>();
    
            // 创建10个任务并执行
            for (int i = 0; i < 10; i++) {
                // 使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中
                Future<String> future = executorService.submit(new TaskWithResult(i));
                // 将任务执行结果存储到List中
                resultList.add(future);
            }
            executorService.shutdown();
    
            // 遍历任务的结果
            for (Future<String> fs : resultList) {
                try {
                    System.out.println(fs.get()); // 打印各个线程(任务)执行的结果
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    executorService.shutdownNow();
                    e.printStackTrace();
                    return;
                }
            }
        }
    }
    class TaskWithResult implements Callable<String> {
        private int id;
    
        public TaskWithResult(int id) {
            this.id = id;
        }
    
        /**
         * 任务的具体过程,一旦任务传给ExecutorService的submit方法,则该方法自动在一个线程上执行。
         *
         * @return
         * @throws Exception
         */
        public String call() throws Exception {
            System.out.println("call()方法被自动调用,干活!!!             " + Thread.currentThread().getName());
            if (new Random().nextBoolean())
                throw new TaskException("Meet error in task." + Thread.currentThread().getName());
            // 一个模拟耗时的操作
            for (int i =9; i > 0; i--)
                ;
            return "call()方法被自动调用,任务的结果是:" + id + "    " + Thread.currentThread().getName();
        }
    }
    
    class TaskException extends Exception {
        public TaskException(String message) {
            super(message);
        }
    }
    call()方法被自动调用,干活!!!             pool-1-thread-5
    call()方法被自动调用,干活!!!             pool-1-thread-1
    call()方法被自动调用,干活!!!             pool-1-thread-2
    call()方法被自动调用,干活!!!             pool-1-thread-4
    call()方法被自动调用,干活!!!             pool-1-thread-6
    call()方法被自动调用,干活!!!             pool-1-thread-6
    call()方法被自动调用,干活!!!             pool-1-thread-4
    call()方法被自动调用,干活!!!             pool-1-thread-2
    call()方法被自动调用,干活!!!             pool-1-thread-3
    call()方法被自动调用,干活!!!             pool-1-thread-7
    call()方法被自动调用,任务的结果是:0    pool-1-thread-1
    call()方法被自动调用,任务的结果是:1    pool-1-thread-2
    java.util.concurrent.ExecutionException: com.company.TaskException: Meet error in task.pool-1-thread-3
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:192)
        at com.company.Main.main(Main.java:29)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
    Caused by: com.company.TaskException: Meet error in task.pool-1-thread-3
        at com.company.TaskWithResult.call(Main.java:56)
        at com.company.TaskWithResult.call(Main.java:40)
        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)
    View Code

    Runnable和Callable的区别是,
    (1)Callable规定的方法是call(),Runnable规定的方法是run().
    (2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
    (3)call方法可以抛出异常,run方法不可以
    (4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

    http://blog.csdn.net/yuzhiboyi/article/details/7775266

    http://blog.csdn.net/zhangzhaokun/article/details/6615454

    http://blog.csdn.net/xtwolf008/article/details/7713580

  • 相关阅读:
    install sklearn-crfsuite on mac
    排序算法之选择排序
    排序算法之冒泡排序
    Python中__init__与self的解释
    Python中 if __name__ == "__main__"解释
    Python活力练习Day25
    Python活力练习Day24
    Python活力练习Day23
    动态规划之编辑距离
    Python活力练习Day22
  • 原文地址:https://www.cnblogs.com/hongdada/p/6122437.html
Copyright © 2011-2022 走看看