java多线程 Callable与Future

    技术2023-08-02  63

    一、 java.util.concurrent.Callable Callable 接口 与 Runnable 接口类似,不同的是它们的唯一的 run 方法: 1、Callable 有返回值,Runnable 没有。    Callable 的 run() 方法使用了 泛型类,可以返回任意类型的值。 2、Callable 抛出异常 ,Runnable 没有抛出。 同时 java.util.concurrent.Executors 提供了许多方法,可以操控 Callable 在线程池中运行。二、java.util.concurrent.Future Executors 执行 Callable 时会返回一个 Future 对象。使用 Future 我们可以得知 Callable 的运行状态, 以及获取 Callable 执行完后的返回值。 Future 的方法介绍:     - get() :阻塞式,用于获取 Callable/Runnable 执行完后的返回值。               带时间参数的get()重载方法用于最多等待的时间后,如仍未返回则线程将继续执行。     - cancel() :撤销正在执行 Callable 的 Task。     - isDone():是否执行完毕。     - isCancelled():任务是否已经被取消。   三、使用实例     100个任务各耗时 1 秒,用 10 个线程并行执行。

    java代码

    import java.util.ArrayList;  import java.util.Date;  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.Future;    import org.junit.Test;    public class T03_MyCallable implements Callable<String> {        @Override      public String call() throws Exception {          Thread.sleep(1000);          return Thread.currentThread().getName();      }                  @Test      public void testName() throws Exception {          ExecutorService executor = Executors.newFixedThreadPool(10);          List<Future<String>> callableList = new ArrayList<Future<String>>();          Callable<String> callable = new T03_MyCallable();          for(int i=0; i< 100; i++){              Future<String> future = executor.submit(callable);              callableList.add(future);          }          for(Future<String> future : callableList){              try {                  System.out.println(new Date()+ "::"+future.get());//blocked.              } catch (InterruptedException | ExecutionException e) {                  e.printStackTrace();              }          }          //shut down the executor service now          executor.shutdown();      }            /**        NOTE:        main thread should not complete earlier than sub thread,        should at least wait for one task execution time in main thread,        should use : future.get() method in main thread.        or use: executor.awaitTermination(timeout, unit) in main thread.      */  } 

    结果

    Sun Jan 08 22:01:55 CST 2017::pool-1-thread-1  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-2  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-3  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-4  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-5  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-6  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-7  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-8  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-9  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-10  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-1  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-3  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-5  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-7  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-9  ...  ...  ...  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-2  Sun Jan 08 22:01:55 CST 2017::pool-1-thread-4  Sun Jan 08 22:01:56 CST 2017::pool-1-thread-8  

     

    Processed: 0.013, SQL: 9