多线程(二)

主要的说明承接上面的InvokeAny/All 的说明,主要是代码的说明,接下来会对源码的说明:

import java.util.concurrent.Callable;

/*
 * 这是一个可能会在执行过程中,抛出空指针异常的任务。
 * */
public class ExceptionCallable implements Callable<String> {
    private String name = null;

    public ExceptionCallable() {
    }

    public ExceptionCallable(String name) {
        this.name = name;
    }

    @Override
    public String call() throws Exception {
        System.out.println("begin to ExceptionCallable.");
        System.out.println(name.length());
        System.out.println("end to ExceptionCallable.");
        return name;
    }
}
import java.util.Random;
import java.util.concurrent.Callable;

//短时任务,随即按产生10个数字
public class RandomTenCharsTask implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("RandomTenCharsTask begin to execute...");
        StringBuffer content = new StringBuffer();
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            int number = random.nextInt(base.length());
            content.append(base.charAt(number));
        }
        System.out.println("RandomTenCharsTask complete.result=" + content);
        return content.toString();
    }
}
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
 * 这是一个通过睡眠来模拟的耗时任务,该任务是可中断/可终止的任务,能够响应中断请求。
 * */

public class SleepSecondsCallable implements Callable<String> {
    private String name;
    private int seconds;

    public SleepSecondsCallable(String name, int seconds) {
        this.name = name;
        this.seconds = seconds;
    }

    public String call() throws Exception {
        System.out.println(name + ",begin to execute");
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException e) {
            System.out.println(name + " was disturbed during sleeping.");
            e.printStackTrace();
            return name + "_SleepSecondsCallable_failed";
        }
        System.out.println(name + ",success to execute");
        return name + "_SleepSecondsCallable_succes";
    }
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class Snippet {
    
    public static void main(String[] args) throws Exception{
//        invokeAny1();
        invokeAny2();
    }
    
    /**
     * 提交的任务集合,一旦有1个任务正常完成(没有抛出异常),会终止其他未完成的任务
     * 此方法中输出是:
     */
    public static void invokeAny1() throws Exception
    {
      ExecutorService executorService = Executors.newFixedThreadPool(3);
      List<Callable<String>> tasks = new ArrayList<Callable<String>>();
      tasks.add(new SleepSecondsCallable("t1", 2));
      tasks.add(new SleepSecondsCallable("t2", 1));
      String result = executorService.invokeAny(tasks);
      System.out.println("result=" + result);
      executorService.shutdown();
    }

    /* 此invokeAny1()方法的输出结果:
     * t2,begin to execute
     * t1,begin to execute
     * t2,success to execute
     * java.lang.InterruptedException: sleep interrupted
     * result=t2_SleepSecondsCallable_succes
     * t1 was disturbed during sleeping.
     * 一个任务执行完成以后,会终止其他未完成的任务
     */
    
    /**
    * 没有1个正常完成的任务,invokeAny()方法抛出ExecutionException,
    * 封装了任务中元素的异常
    */
    public static void invokeAny2() throws Exception
    {
      ExecutorService executorService = Executors.newFixedThreadPool(3);
      List<Callable<String>> tasks = new ArrayList<Callable<String>>();
      tasks.add(new ExceptionCallable());
      tasks.add(new ExceptionCallable());
      tasks.add(new ExceptionCallable());
      String result = executorService.invokeAny(tasks);
      System.out.println("result=" + result);
      executorService.shutdown();
    }
    /*invokeAny2()执行的结果:
     * begin to ExceptionCallable.
     * begin to ExceptionCallable.
     * begin to ExceptionCallable.
     * Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NullPointerException
     * 具体的那个线程抛出来的错误,就无所谓了。
     * /
    
    /**
    * 有异常的任务,有正常的任务,invokeAny()不会抛异常,返回最先正常完成的任务
    */
    public static void invokeAny3() throws Exception
    {
      ExecutorService executorService = Executors.newFixedThreadPool(3);
      List<Callable<String>> tasks = new ArrayList<Callable<String>>();
      tasks.add(new ExceptionCallable());
      tasks.add(new ExceptionCallable());
      tasks.add(new ExceptionCallable());
      tasks.add(new ExceptionCallable());
      tasks.add(new SleepSecondsCallable("t1", 2));
      String result = executorService.invokeAny(tasks);
      System.out.println("result=" + result);
      executorService.shutdown();
    }

    /**
     * 还没有到超时之前,所以的任务都已经异常完成,抛出ExecutionException<br>
     * 如果超时前满,还没有没有完成的任务,抛TimeoutException
     */
    public static void invokeAnyTimeout() throws Exception
    {
      ExecutorService executorService = Executors.newFixedThreadPool(3);
      List<Callable<String>> tasks = new ArrayList<Callable<String>>();
      tasks.add(new ExceptionCallable());
      tasks.add(new ExceptionCallable());
      tasks.add(new ExceptionCallable());
      tasks.add(new ExceptionCallable());
      String result = executorService.invokeAny(tasks, 2, TimeUnit.SECONDS);
      System.out.println("result=" + result);
      executorService.shutdown();
    }

    /*
     * 测试invokeAll
     * */
    public static void testInvokeAll() throws Exception
    {
      ExecutorService executorService = Executors.newFixedThreadPool(5);
      List<Callable<String>> tasks = new ArrayList<Callable<String>>();
      tasks.add(new SleepSecondsCallable("t1", 2));
      tasks.add(new SleepSecondsCallable("t2", 2));
      tasks.add(new RandomTenCharsTask());
      tasks.add(new ExceptionCallable());
      // 调用该方法的线程会阻塞,直到tasks全部执行完成(正常完成/异常退出)
      List<Future<String>> results = executorService.invokeAll(tasks);
      // 任务列表中所有任务执行完毕,才能执行该语句
      System.out.println("wait for the result." + results.size());
      executorService.shutdown();
      for (Future<String> f : results)
      {
        // isCanceled=false,isDone=true
        System.out.println("isCanceled=" + f.isCancelled() + ",isDone="
            + f.isDone());
        // ExceptionCallable任务会报ExecutionException
        System.out.println("task result=" + f.get());
      }
    }

}
原文地址:https://www.cnblogs.com/zhailzh/p/3971063.html