线程池ExecutorService

来源:互联网 发布:阿里巴巴网络银行 编辑:程序博客网 时间:2024/06/05 16:03

学习Java的时候并没有深入的了解ExecutorService,但是在做Android项目开发的时候使用到ExecutorService线程池。开始并不怎么理解,在网上查阅一下资料,并观看了Java API文档理解了ExecutorService的使用,特写出此博客方便自己和大家阅读,有理解错误的地方希望阅读者可以指出,谢谢!

创建ExecutorService对象

创建ExecutorService对象常用的方法有以下四种

// 创建可以容纳3个线程的线程池ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);// 线程池的大小会根据执行的任务数动态分配ExecutorService cachedThreadPool = Executors.newCachedThreadPool();// 创建单个线程的线程池,如果当前线程在执行任务时突然中断,则会创建一个新的线程替代它继续执行任务ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();// 效果类似于Timer定时器ScheduledExecutorService scheduledThreadPool = Executors        .newScheduledThreadPool(3);

我在下面写一个示例方便大家的理解:

示例:

public class Example {    private static void run(ExecutorService threadPool) {        for (int i = 0; i < 4; i++) {            final int threadId = i;            threadPool.execute(new Runnable() {                @Override                public void run() {                    for (int i = 0; i < 4; i++) {                        try {                            Thread.sleep(30);// 为了测试出效果,让每次任务执行都需要一定时间                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                        System.out.println("第" + threadId + "次线程的第" + i + "次执行");                    }                }            });        }        threadPool.shutdown();//养成良好的编程习惯,关闭线程池     }    public static void main(String[] args) {        // 创建可以容纳3个线程的线程池        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);        // 线程池的大小会根据执行的任务数动态分配        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();        // 创建单个线程的线程池,如果当前线程在执行任务时突然中断,则会创建一个新的线程替代它继续执行任务        ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();        // 效果类似于Timer定时器        ScheduledExecutorService scheduledThreadPool = Executors                .newScheduledThreadPool(3);        run(fixedThreadPool);        // run(cachedThreadPool);        // run(singleThreadPool);        // run(scheduledThreadPool);    }}

FixedThreadPool

在FixedThreadPool中,有一个固定大小的池。如果当前需要执行的任务超过池大小,那么多出的任务处于等待状态,直到有空闲下来的线程执行任务,如果当前需要执行的任务小于池大小,空闲的线程也不会去销毁。

执行结果:

0次线程的第0次执行第2次线程的第0次执行第1次线程的第0次执行第1次线程的第1次执行第2次线程的第1次执行第0次线程的第1次执行第2次线程的第2次执行第0次线程的第2次执行第1次线程的第2次执行第1次线程的第3次执行第0次线程的第3次执行第2次线程的第3次执行第3次线程的第0次执行第3次线程的第1次执行第3次线程的第2次执行第3次线程的第3次执行

CachedThreadPool

CachedThreadPool会创建一个缓存区,将初始化的线程缓存起来。会终止并且从缓存中移除已有60秒未被使用的线程。如果线程有可用的,就使用之前创建好的线程,
如果线程没有可用的,就新创建线程。注意,放入CachedThreadPool的线程不必担心其结束,超过TIMEOUT不活动,其会自动被终止。

执行结果:

3次线程的第0次执行第2次线程的第0次执行第1次线程的第0次执行第0次线程的第0次执行第0次线程的第1次执行第1次线程的第1次执行第3次线程的第1次执行第2次线程的第1次执行第3次线程的第2次执行第2次线程的第2次执行第0次线程的第2次执行第1次线程的第2次执行第2次线程的第3次执行第3次线程的第3次执行第0次线程的第3次执行第1次线程的第3次执行

SingleThreadExecutor

SingleThreadExecutor得到的是一个单个的线程,这个线程会保证你的任务执行完成。如果当前线程意外终止,会创建一个新线程继续执行任务,这和我们直接创建线程不同,也和newFixedThreadPool(1)不同。

执行结果:

0次线程的第0次执行第0次线程的第1次执行第0次线程的第2次执行第0次线程的第3次执行第1次线程的第0次执行第1次线程的第1次执行第1次线程的第2次执行第1次线程的第3次执行第2次线程的第0次执行第2次线程的第1次执行第2次线程的第2次执行第2次线程的第3次执行第3次线程的第0次执行第3次线程的第1次执行第3次线程的第2次执行第3次线程的第3次执行

ScheduledThreadPool

ScheduledThreadPool是一个固定大小的线程池,与FixedThreadPool类似,执行的任务是定时执行

执行结果:

1次线程的第0次执行第2次线程的第0次执行第0次线程的第0次执行第2次线程的第1次执行第1次线程的第1次执行第0次线程的第1次执行第0次线程的第2次执行第2次线程的第2次执行第1次线程的第2次执行第1次线程的第3次执行第2次线程的第3次执行第0次线程的第3次执行第3次线程的第0次执行第3次线程的第1次执行第3次线程的第2次执行第3次线程的第3次执行

看完示例大家应该更加深刻的理解了ExecutorService的机制了吧!如果博客中解释错误或者不清晰,请读者留言指教。谢谢!

1 0