并发编程之使用Executor

  • Post author:
  • Post category:其他


Executor将用来管理Thread对象,Executor在客户端和任务之间提供了一个间接层,与客户端直接执行任务不同,这个中介将执行任务。Executor允许你管理异步任务的执行,而无须显式地管理线程的生命周期。Executor在Java SE5/6是启动任务的优选方法。

ExecutorService:具有服务生命周期的Executor,知道如何构建恰当的上下文来执行Runnable对象。

package bingfa;
class LiftOff implements Runnable{
    protected int countdown = 10;
    private static int taskCount = 0;
    private final int id = taskCount++;
    public LiftOff(){}
    public LiftOff(int countdown){
        this.countdown = countdown;
    }
    public String status(){
        return "#"+id + "("+(countdown > 0 ? countdown :"Liftdown!")+"),";
    }
    public void run(){
        while (countdown --> 0){
            System.out.println(status());
            Thread.yield();
        }
    }
}
package bingfa;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CachedThreadPool {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for(int i=0;i<5;i++){
            executorService.execute(new LiftOff());

        }
        executorService.shutdown();
        System.out.println("11111");
    }
}

常见情况:单个的Executor被用来创建和管理系统中所有的任务。

对shutdown()方法的调用可以防止新任务被提交给这个Executor.

CachedThreadPool在程序执行过程中通常会创建于所需数量相同的线程,然后在它回收旧线程时停止创建新线程,因此它时合理的Executor首选,只有当这种方式会引发问题时,才需要切换FixedThreadPool。


Callable接口:

Runnable是执行工作的独立任务,但是它不返回任何值。Callable接口是一种具有参数类型的泛型,它的类型参数表示的是从方法call()中返回的值,并且必须使用ExecutorService.submit()方法调用它。

​
package bingfa;

import java.util.ArrayList;
import java.util.concurrent.*;

class TaskWithResult implements Callable<String>{
    private int id;
    public TaskWithResult(int id){
        this.id = id ;
    }
    public String call(){
        return "result of TaskWithResult "+id;
    }
}
public class CallableDemo {
    public static void main(String[] args) {
        ExecutorService exec = Executors.newCachedThreadPool();
        ArrayList<Future<String>> results = new ArrayList<Future<String>>();
        for (int i=0;i<10;i++){
            results.add(exec.submit(new TaskWithResult(i)));
        }
        for(Future<String> fs :results){
            try {
                System.out.println(fs.get());
                System.out.println(fs.isDone());
            } catch (InterruptedException e) {
                System.out.println(e);
            } catch (ExecutionException e) {
                System.out.println(e);
                return;
            }finally {
                exec.shutdown();
            }
        }
    }
}

​

submit()方法会产生Future对象,它用Callable返回结果的特定类型进行了参数化。可以用isDone()方法来查询Future是否完成。



版权声明:本文为weixin_42759988原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。