java线程池框架

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实现类

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()方法。 它将立刻停止所有执行任务,并跳过所有提交了但未处理的任务。正在执行的任务无法确定如果结束,可能立刻停止,可能直到执行完成停止。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值