zoukankan      html  css  js  c++  java
  • java多线程批量执行的时限问题

    需求:需要并发执行三个线程,要求在指定的时间内返回结果,如果某个线程超时,则返回为空。

    思路:使用ExecutorService的invokeAll(time,timeUint)方法来设置执行时限,该方法返回一个List<Future<T>>,一旦返回后,即取消尚未完成的任务,然后再从list中读取future并调用future.get()方法来获取线程返回的结果,如果future.get()抛出CancellationException 则说明该任务未完成被取消了。

    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout,
                                  TimeUnit unit)
                              throws InterruptedException执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future 列表。返回列表的所有元素的 Future.isDone() 为 true。一旦返回后,即取消尚未完成的任务。注意,可以正常地或通过抛出异常来终止已完成 任务。如果此操作正在进行时修改了给定的 collection,则此方法的结果是不确定的。 
    
    参数:
    tasks - 任务 collection
    timeout - 最长等待时间
    unit - timeout 参数的时间单位 
    返回:
    表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同。如果操作未超时,则已完成所有任务。如果确实超时了,则某些任务尚未完成。 
    抛出: 
    InterruptedException - 如果等待时发生中断,在这种情况下取消尚未完成的任务 
    NullPointerException - 如果任务或其任意元素或 unit 为 null 
    RejectedExecutionException - 如果所有任务都无法安排执行
    public class CallableAndFutureTask {
    
        /**
         * @param args
         */
        public static class MyCallable implements Callable<String>{
            
            private String name;
            private int age;
            
            public MyCallable(String name, int age) {
                // TODO Auto-generated constructor stub
                this.name = name;
                this.age = age;
            }
    
            @Override
            public String call() throws Exception {
                // TODO Auto-generated method stub
                Thread.sleep(new Random().nextInt(4000));
                return "name:"+this.name+" "+"age:"+this.age;
            }
            
        }
        
        public static void main(String[] args) {
            //callable 执行任务,future得到任务执行结果
            ExecutorService threadPool =  Executors.newFixedThreadPool(3);
    
            int i = 10;
            while(i-- > 0){
            //创建一个tasks的list
                List<MyCallable> tasks = new ArrayList<MyCallable>();
                tasks.add(new MyCallable("tom", 20));
                tasks.add(new MyCallable("john", 30));
                tasks.add(new MyCallable("jack", 40));
           //用来接收任务执行结果 List
    <Future<String>> taskResult = null; List<String> result = new ArrayList<String>(); System.out.println("等待结果:"+i); Long s = System.currentTimeMillis(); try { taskResult = threadPool.invokeAll(tasks, 3000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int j = 0; j < 3; j ++){ try { result.add(taskResult.get(j).get()); } catch (CancellationException e) { // TODO Auto-generated catch block // e.printStackTrace(); System.out.println(j+"cancled"); }catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("执行时间:"+(System.currentTimeMillis()-s)/1000); if(result.size() == 0){ System.out.println("get no data"); }else{ System.out.println(result); } } } }

    和简单的future callable比较,ExecutorService 的submit方法中不能设置时限,只能使用future.get(time,timeUint),但这样一来,再接收结果时就变成了串行,即接收每个任务的结果都需要time的时间,三个任务的执行就变成了3*time,对于单个任务设置超时可以使用这种方式

    package com.newTechnologyInJava5;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.CancellationException;
    import java.util.concurrent.CompletionService;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorCompletionService;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    
    
    public class CallableAndFutureTask {
    
        /**
         * @param args
         */
        public static class MyCallable implements Callable<String>{
            
            private String name;
            private int age;
            
            public MyCallable(String name, int age) {
                // TODO Auto-generated constructor stub
                this.name = name;
                this.age = age;
            }
    
            @Override
            public String call() throws Exception {
                // TODO Auto-generated method stub
                Thread.sleep(new Random().nextInt(4000));
                return "name:"+this.name+" "+"age:"+this.age;
            }
            
        }
        
        public static void main(String[] args) {
            //callable 执行任务,future得到任务执行结果
            ExecutorService threadPool =  Executors.newFixedThreadPool(3);
    
            int i = 10;
            while(i-- > 0){
    
                Future<String> future1 = threadPool.submit(new MyCallable("tom", 20));
                Future<String> future2 = threadPool.submit(new MyCallable("john", 30));
                Future<String> future3 = threadPool.submit(new MyCallable("jack", 40));
                try {
                    
                    try {
                        result.add(future1.get(3000, TimeUnit.MILLISECONDS));
                        
                    } catch (TimeoutException e) {
                        // TODO Auto-generated catch block
    
                        future1.cancel(true);
                    }
                    try {
                        result.add(future2.get(3000, TimeUnit.MILLISECONDS));
                        
                    } catch (TimeoutException e) {
                        // TODO Auto-generated catch block
    
                        future2.cancel(true);
                    }
                    try {
                        result.add(future3.get(3000, TimeUnit.MILLISECONDS));
                        
                    } catch (TimeoutException e) {
                        // TODO Auto-generated catch block
    
                        future3.cancel(true);
                    }
                    
        
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if(result.size() == 0){
                    System.out.println("get no data");
                }else{
                    System.out.println(result);
                }
                
            }
        }
    
    }
  • 相关阅读:
    Web应用程序并发问题处理的一点小经验
    *.pvr.ccz文件还原成png格式
    在python 中is和= = 的区别
    pyhton,数据类型
    python,序列化
    python, 操作文件和目录
    python文件,字符串,二进制的读写
    io编程,python
    python,错误、调试和测试
    python,多线程
  • 原文地址:https://www.cnblogs.com/vitosun/p/5377307.html
Copyright © 2011-2022 走看看