【线程】Executor

在生产环境中,为每一个任务分配一个线程,尤其是在大量创建线程的时候是由一定缺陷的:

  • 线程生命周期的开销非常高。线程的创建与销毁需要JVM和操作系统提供一些辅助操作,如果请求率非常高,那么为每个请求创建一个新线程将消耗大量的计算资源。

  • 资源消耗高。活跃的线程会消耗大量的内存资源。

  •  稳定性差。线程过多可能抛出OutOfMemoryError异常。


Executor 和 Executors


Executor是提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节、调度等)分离开来的方法。通常使用Executor来创建线程,而不是使用new Thread显示的创建线程。

Executors可以理解为Executor的工厂类。提供了创建Executor类型的工厂方法。

程序一:为每一个任务创建一个线程


public class AsynExecutor implements Executor{
    @Override
    public void execute(Runnable command) {
        new Thread(command).start();
    }

    public static void main(String[] args) {
        AsynExecutor ae = new AsynExecutor();
        for(int i=0;i<5;i++) {
            ae.execute(new MyRunnable(""+i));
        }
    }
}

public class MyRunnable implements Runnable {

    String name ;

    public MyRunnable(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(name + " 执行任务");
    }

}


程序二:顺序执行任务


public class SynExecutor implements Executor{
    @Override
    public void execute(Runnable command) {
        command.run(); 
    }

    public static void main(String[] args) {
        SynExecutor se = new SynExecutor();
        for(int i=0;i<5;i++) {
            se.execute(new MyRunnable(""+i));
        }
    }
}


Executor 生命周期

Executor扩展了ExecutorService接口,添加了一些用于管理生命周期的方法与便于任务提交的方法。

ExecutorService的状体分为运行关闭终止。在初始创建时处于运行状态。shutdown方法将执行平缓的的关闭过程,启动一次顺序关闭,执行以前提交的任务,但不接受新任务;shutdownNow方法执行粗暴的关闭过程,试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。


 程序三:Executor的生命周期


public class ExecutorLifeCycle {

    static volatile int i=0;
    public static void main(String[] args) {

        ExecutorService es = Executors.newFixedThreadPool(3);

        es.execute(new Runnable() {
            @Override
            public void run() {
                while(true) {
                        if(i == 2) {
                            es.shutdown();
                            System.out.println("执行关闭的动作");
                            break;
                        }
                }
            }
        });


        for(i=0;i<3;i++) {
            try {
                Thread.sleep(400);

                if(!es.isShutdown()) {
                    System.out.println("加入到es的线程i = "+i);
                    es.execute(new MyRunnable("加入的线程:"+i));
                }

            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    }
}

如果ExecutorService不关闭,程序将不会退出

  

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页