java线程池框架
java.util.concurrent.ExecutorService
接口表现异步执行机制,使任务在后台执行。ExecutorService在包java.util.concurrent中作为线程池实现类。
ExecutorService 示例
简单的Java ExectorService
示例:
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
executorService.shutdown();
使用工厂方法创建ExecutorService线程池对象,包含10个线程。然后一个Runnable接口的匿名实现,传给execute方法。ExecutorService线程池中的一个线程负责执行。
委托任务异步执行
图示一个线程委托一个任务给 |
ExecutorService实现类
ExecutorService是接口,实际使用需要有对应实现类。在java.util.concurrent包有下面的实现类。
Creating anExecutorService
如何通过ExecutorService
实现类创建ExecutorService,一般可以通过Executors的工厂方法创建ExecutorService实现类,下面三个示例代码
:
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
ExecutorService executorService2 = Executors.newFixedThreadPool(10);
ExecutorService executorService3 = Executors.newScheduledThreadPool(10);
ExecutorService 常用方法
有几种方式可以委托任务给ExecutorService去执行。
- execute(Runnable)
- submit(Runnable)
- submit(Callable)
- invokeAny(...)
- invokeAll(...)
下面依次说明每个方法。
execute(Runnable)
execute(Runnable)
方法需要一个java.lang.Runnable接口实现对象
,异步执行。示例如下:
<pre name="code" class="java">ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
executorService.shutdown();
上面代码无法获得执行的Runnable的结果,可以通过Callable实现,请继续往下阅读。
submit(Runnable)
The submit(Runnable)
方法也需要一个Runnable
接口实现对象, 但可以返回一个Future对象。Future
对象可以用来检查Runnable任务是否执行完成。示例代码如下:
Future future = executorService.submit(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
future.get(); //如果任务正确执行完毕,返回null值。
submit(Callable)
The submit(Callable)
方法与submit(Runnable)方法类似,但参数类型不同。Callable
实例与Runnable差不多,除了Callable.call()
方法能返回一个结果,Runnable.run()方法不能有返回值。
Callable的结果可以通过Future对象获得,示例代码如下:
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());
上面的代码输出如下:
Asynchronous Callable
future.get() = Callable Result
invokeAny()
invokeAny()
方法需要Callable
集合对象,或Callable的子接口对象集合。执行该方法不返回Future对象
,但返回其中一个Calllable对象的执行结果,但无法确认是具体那个Callable的对象,仅是所有执行完成对象的其中一个。如果其中一个任务完成(或在抛出异常),剩下的Calllable任务将取消继续执行。示例代码如下:
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();
上述代码将打印集合中一个Calllable任务返回值,我测试了几次,结果都不同,有时是"Task 1",有时是"Task 2",情况不确定。
invokeAll()
invokeAll()
方法执行传递的参数集合中所有的Callable对象。invokeAll()
返回一个Future
对象list,通过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的Shutdown方法
当使用ExecutorService时,最后应该调用
shutdown方法,这样所有的线程将不再运行。
例如,如果你的应用通过main方法启动,则主线程负责结束应用程序。如果你应用中ExexutorService
是活动的,则应用继续保持运行状态。活动的ExexutorService
阻止JVM停止应用。
为了终止ExecutorService里的线程任务,你可以调用shutdown()
方法。但ExecutorService并不立刻停止
,但不在接受新的任务,一旦所有的线程都完成了当前任务,ExecutorService停止。所有提交到ExecutorService的任务在调用shutdown()方法之前被执行。
如果你想立刻结束ExecutorService
,你可以调用shutdownNow()
方法。 它将立刻停止所有执行任务,并跳过所有提交了但未处理的任务。正在执行的任务无法确定如果结束,可能立刻停止,可能直到执行完成停止。
本文参考链接:https://blog.csdn.net/neweastsun/article/details/52565891