package com.zhl.practice; import java.util.concurrent.*; /** * @author Holley * @Description 多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程( 其中callable依赖于线程池) * @create 2019-05-27 11:20 **/ public class CallableAndFutureTest { public static void main(String[] args){ // 创建线程池(单线程) // ExecutorService executorService = Executors.newSingleThreadExecutor(); // 具有固定条数线程的线程池 ExecutorService executorService = Executors.newFixedThreadPool(2); // 可变线程池,当线程数不够时,自动新增线程 // ExecutorService executorService = Executors.newCachedThreadPool(); // 无返回值的线程调用 // executorService.execute(new Runnable() { // @Override // public void run() { // System.out.println("线程执行任务代码"); // } // }); //具有返回值的线程调用 Future future = executorService.submit( new Callable<String>() { @Override public String call() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } return "测试结果:aaa"; } } ); executorService.execute(new Runnable() { @Override public void run() { int i = 0; while (i < 6){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis()); i++; } } }); try { // 获取线程返回结果会等待该线程执行完毕之后才会返回,此代码中将在5秒后打印出 线程返回值:测试结果:aaa System.out.println("线程返回值:" + future.get()); // 强制在一秒钟后获取返回结果,如果获取不到此时会抛出异常java.util.concurrent.TimeoutException // System.out.println("线程返回值:" + future.get(1,TimeUnit.SECONDS)); } catch (Exception e) { e.printStackTrace(); } // completionService用于提交一组任务,其take方法返回已完成的一个Callable任务对应的Futrue对象 ExecutorService executorService12 = Executors.newSingleThreadExecutor(); // CompletionService是一个接口,只能通过他的实现类ExecutorCompletionService来创建实例化 CompletionService<String> completionService = new ExecutorCompletionService(executorService12); // 提交十条任务 for(int i = 1;i<10;i++) { // 只能定义成final型变量才能在下面重写的new Callable(){ call(){}}方法中调用 final int taskId = i; completionService.submit(() -> { Thread.sleep(1000); System.out.println("任务id:" + taskId); return "结果"+taskId; }); } try { for(int i = 1;i<10;i++) { // 每次只输出一个任务的返回值(无固定顺序) System.out.println(completionService.take().get()); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }