关于java:Java线程池ExecutorService中重要的方法

30次阅读

共计 3583 个字符,预计需要花费 9 分钟才能阅读完成。

ExecutorService 介绍

ExecutorServicejava 线程池定义的一个接口, 它在 java.util.concurrent 包中, 在这个接口中定义了和后台任务执行相干的办法。

Java API 对 ExecutorService 接口实现有两个, 所以这两个即是线程池的具体实现。

1. ThreadPoolExecutor
2. ScheduledThreadPoolExecutor

ExecutorService还继承了 Executor 接口。

实线示意继承, 须要示意实现

ExecutorService的创立

Java提供了一个工厂类 Executors 来创立各种线程池。

  • newCachedThreadPool 创立一个可缓存的线程池, 如果线程池长度超过解决须要, 可灵便回收闲暇线程, 如果没有能够回收的, 则新建线程。
  • newFixedThreadPool 创立一个定长的线程池, 可控制线程最大并发数, 超出的线程会在队列中期待。
  • newScheduledThreadPool 创立一个定长线程池, 能够定时周期性执行工作。
  • newSingleThreadPool 创立一个单线程线程池, 它只会用惟一的线程来执行工作, 保障所有工作依照指定程序来执行(FIFO,LIFO)

Executors是一个工厂类, 它所有的办法返回的都是 ThreadPoolExecutorScheduledThreadPoolExecutor这两个类的实例。

ExecutorService的应用

ExecutorService executorService = Executors.newFixedThreadPool(10);

executorService.execute(new Runnable() {public void run() {System.out.println("入门小站");
}
});

executorService.shutdown();

ExecutorService的执行办法

  • execute(Runnable)
  • submit(Runnable)
  • submit(Callable)
  • invokeAny(…)
  • invokeAll(…)

execute(Runnable) 无奈获取执行后果

接管一个 Runnable 实例, 并且异步执行

ExecutorService executorService = Executors.newSingleThreadExecutor();

executorService.execute(new Runnable() {public void run() {System.out.println("Asynchronous task");
}
});

executorService.shutdown();

没有方法获取执行后果。

submit(Runnable) 能够判断工作是否实现

submit(Runnable)execute(Runnable) 多返回一个Future, 能够用来判断提交的工作是否执行实现。

Future future = executorService.submit(new Runnable() {public void run() {System.out.println("Asynchronous task");
}
});

future.get();  //returns null if the task has finished correctly.

如果工作实现,future.get()会返回 null,future.get会阻塞。

submit(Callable)能够获取返回后果

submit(Callable)和 submit(Runnable)相似,也会返回一个 Future 对象,然而除此之外,submit(Callable)接管的是一个 Callable 的实现,Callable 接口中的 call()办法有一个返回值,能够返回工作的执行后果,而 Runnable 接口中的 run()办法是 void 的,没有返回值

Future future = executorService.submit(new Callable(){public Object call() throws Exception {System.out.println("Asynchronous Callable");
    return "Callable Result";
}
});

System.out.println("future.get() =" + future.get());

如果工作实现,future.get会返回 Callable 执行返回的后果, 同样 future.get() 会阻塞。

invokeAny(…)

invokeAny(...)办法接管的是一个 Callable 的汇合,执行这个办法不会返回 Future,然而会返回所有 Callable 工作中其中一个工作的执行后果。这个办法也无奈保障返回的是哪个工作的执行后果,反正是其中的某一个

ExecutorService executorService = Executors.newSingleThreadExecutor();

Set<Callable<String>> callables = new HashSet<Callable<String>>();

callables.add(new Callable<String>() {public String call() throws Exception {return "Task 1";}
});
callables.add(new Callable<String>() {public String call() throws Exception {return "Task 2";}
});
callables.add(new Callable<String>() {public String call() throws Exception {return "Task 3";}
});

String result = executorService.invokeAny(callables);
System.out.println("result =" + result);
executorService.shutdown();

每次执行都会返回一个后果,并且返回的后果是变动的,可能会返回“Task2”也可是“Task1”或者其它。

invokeAll(...)

invokeAll(…)与 invokeAny(…)相似也是接管一个 Callable 汇合,然而前者执行之后会返回一个 Future 的 List,其中对应着每个 Callable 工作执行后的 Future 对象。

ExecutorService executorService = Executors.newSingleThreadExecutor();

Set<Callable<String>> callables = new HashSet<Callable<String>>();

callables.add(new Callable<String>() {public String call() throws Exception {return "Task 1";}
});
callables.add(new Callable<String>() {public String call() throws Exception {return "Task 2";}
});
callables.add(new Callable<String>() {public String call() throws Exception {return "Task 3";}
});

List<Future<String>> futures = executorService.invokeAll(callables);

for(Future<String> future : futures){System.out.println("future.get =" + future.get());
}

executorService.shutdown();

线程池 ExecutorService 的敞开

如果要敞开 ExecutorService 中执行的线程,咱们能够调用 ExecutorService.shutdown()办法。在调用 shutdown()办法之后,ExecutorService 不会立刻敞开,然而它不再接管新的工作,直到以后所有线程执行实现才会敞开,所有在 shutdown()执行之前提交的工作都会被执行。

如果咱们想立刻敞开 ExecutorService,咱们能够调用 ExecutorService.shutdownNow()办法。这个动作将跳过所有正在执行的工作和被提交还没有执行的工作。然而它并不对正在执行的工作做任何保障,有可能它们都会进行,也有可能执行实现。

关注微信公众号:【入门小站】, 解锁更多知识点

正文完
 0