zoukankan      html  css  js  c++  java
  • ExecutorService的invokeAny方法

    一、此方法获得最先完成任务的结果,即Callable<T>接口中的call的返回值,在获得结果时,会中断其他正在执行的任务

    示例代码:

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class MyinvokeAny {
    
    	public static void main(String[] args) {
    		// TODO 自动生成的方法存根
    		List<Callable<String>> list=new ArrayList<Callable<String>>();
    		list.add(new MyCallable_iAny1());
    		list.add(new MyCallable_iAny2());
    		ExecutorService executor=Executors.newCachedThreadPool();
    		
    		try {
    			String str=executor.invokeAny(list);//取出第一个执行完的任务时,其他未完成的任务会被中断
    			System.out.println(str);
    		} catch (InterruptedException e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		} catch (ExecutionException e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}
    		
    		
    	}
    
    }
    class MyCallable_iAny1 implements Callable<String>{
    
    	@Override
    	public String call() throws Exception {
    		// TODO 自动生成的方法存根
    		try{
    			for(int i=0;i<123456;i++){
    				for(int j=0;j<123;j++){
    					if(Thread.currentThread().isInterrupted()){
    						System.out.println("this is a exception");
    						throw new InterruptedException("A InterruptedException");
    					}
    				}
    			}
    		}catch(Exception e){
    			e.printStackTrace();
    			throw e;
    		}
    		
    		System.out.println("finish");
    		return "call_1";
    	}
    	
    }
    class MyCallable_iAny2 implements Callable<String>{
    
    	@Override
    	public String call() throws Exception {
    		// TODO 自动生成的方法存根
    		Thread.sleep(1000);
    		return "call_2";
    	}
    	
    }
    

      运行结果:

    call_2java.lang.InterruptedException: A InterruptedException
    
    this is a exception
    	at myexecutorservice.MyCallable_iAny1.call(myinvokeAny.java:53)
    	at myexecutorservice.MyCallable_iAny1.call(myinvokeAny.java:1)
    	at java.util.concurrent.FutureTask.run(Unknown Source)
    

      

    二、异常的处理

    对于会先完成,但会出现异常的任务,ExecutorService会将关注点换到下一个任务,若果所有的任务都出现异常,那么将会只获得最后一个任务的异常(例如,有3个任务A,B,C,这三个任务都会出现异常,但是只会获得C任务的异常)

    示例代码:

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class myinvokeAny {
    
    	public static void main(String[] args) {
    		// TODO 自动生成的方法存根
    		List<Callable<String>> list=new ArrayList<Callable<String>>();
    		list.add(new MyCallable_iAny1());
    		list.add(new MyCallable_iAny2());
    		ExecutorService executor=Executors.newCachedThreadPool();
    		
    		try {
    			String str=executor.invokeAny(list);//取出第一个执行完的任务时,其他未完成的任务会被中断
    
    			System.out.println(str);
    		} catch (InterruptedException e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		} catch (ExecutionException e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}
    		
    		
    	}
    
    }
    class MyCallable_iAny1 implements Callable<String>{
    
    	@Override
    	public String call() throws Exception {
    		// TODO 自动生成的方法存根
    		Thread.sleep(2000);
    		
    		System.out.println("finish");
    		return "call_1";
    	}
    	
    }
    class MyCallable_iAny2 implements Callable<String>{
    
    	@Override
    	public String call() throws Exception {
    		// TODO 自动生成的方法存根
    		Thread.sleep(1000);
    		if(true){
    			throw new Exception("myException_B");
    		}
    		return "call_2";
    	}
    	
    }
    

      运行结果:

    finish
    call_1
    

      由此,我们可以看出,MyCallable_iAny2任务出现异常,从而将任务的关注点移到了MyCallable_iAny1任务,并不会打印出异常信息。如果,想打印出异常信息,需要这样写:

    写法一:

                    try{
    			if(true){
    				throw new Exception("myException_B");
    			}
    		}catch(Exception e){
    			e.printStackTrace();
    }

    运行结果:

    java.lang.Exception: myException_B
    call_2
    	at myexecutorservice.MyCallable_iAny2.call(myinvokeAny.java:76)
    	at myexecutorservice.MyCallable_iAny2.call(myinvokeAny.java:1)
    

    这里获得了异常任务的结果,这是因为MyCallable_iAny2的异常状态未上报,这导致线程池认为其是正确的,从而未将关注点换到下一个任务

    写法二:

    try{
    			if(true){
    				throw new Exception("myException_B");
    			}
    		}catch(Exception e){
    //			e.printStackTrace();
    			throw e;
    		}
    

    运行结果:

    finish
    call_1
    

      这里抛出了异常,从了线程池将关注点换到了下一个任务

  • 相关阅读:
    java+selenium+new——同一个标签窗口里 ,访问多个网页的后退driver.navigate().back()、前进driver.navigate().forward()、刷新driver.navigate().refresh()等功能 。以及获取当前页面的title属性driver.getTitle()和获取当前页面的url地址driver.getCurrentUrl()
    SoapUI接口测试——关联——参数化
    SoapUI接口测试——添加测试套件——new TestSuite——(类似于postman里面的集合)——添加测试步骤——teststeps(测试步骤)
    java+selenium+new——获取网页源代码driver.getPageSource()
    g++命令行详解
    hdoj_1503Advanced Fruits
    指针遍历vector向量
    最长公共子序列
    hdoj_1087Super Jumping! Jumping! Jumping!
    pcc32应用1
  • 原文地址:https://www.cnblogs.com/l1019/p/6755992.html
Copyright © 2011-2022 走看看