java-线程池(一)

性能优化中,其中一块是线程池的使用,初探线程池,从简单了解到源码分析,深入理解才能合理运用。


(一)线程池的来源及优点

单个异步任务,每次都需创建线程、销毁线程,当任务处理的时间短而请求数却巨大时,将导致资源消耗过多。

比如,数据库连接,需消耗大量资源,建立线程池能重用数据库访问线程。


使用线程池的优点:

1.降低资源消耗。重用现有线程,减少线程创建销毁开销。

2.提高响应速度。任务启动,无需经历线程创建,速度提升。

3.线程控制性强。如定时、定期、单线程设置等。


(二)线程池类别

四种线程池类型:

1.newCachedThreadPool

有缓存的线程池,适用于大量短期任务


2.newFixedThreadPool 

定长的线程池,可控制最大线程并发数


3.newScheduledThreadPool 

定长的线程池,可定时和周期性执行线程


4.newSingleThreadExecutor 

单线程的线程池,保证所有任务按顺序执行


(三)线程池类别实例分析


1.newCachedThreadPool

   private void newCacheThreadPool() {
        ExecutorService threadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            final int index = i;
            try {
                if (i == 1 || i == 3) {
                    Thread.sleep(100);
                }
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            threadPool.execute(new Runnable() {


                @Override
                public void run() {
                    System.out.println("new cached thread pool " + index + ":" +
                        Thread.currentThread().getId());
                }
            });
        }
    }
运行结果:

new cached thread pool 0:9
new cached thread pool 1:9
new cached thread pool 2:10
new cached thread pool 3:10
new cached thread pool 4:9
例子分析:因为1和3线程休息了一下,等待其他线程执行完,所以重用了旧有的线程。


2.newFixedThreadPool 

   private void newFixedThreadPool() {
        ExecutorService threadPool = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 5; i++) {
            final int index = i;
            threadPool.execute(new Runnable() {

                @Override
                public void run() {
                    System.out.println("new fixed thread pool " + index + ":" +
                        Thread.currentThread().getId());
                }
            });
        }
    }
运行结果:

new fixed thread pool 0:9
new fixed thread pool 1:10
new fixed thread pool 2:9
new fixed thread pool 4:9
new fixed thread pool 3:10
例子分析:定长为2,其他线程进入队列,等待前俩线程执行完才运行。

3.newScheduledThreadPool 

    private void newScheduledThreadPool() {
        ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(2);
        try {
            Thread.sleep(100);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadPool.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {
                System.out.println("new scheduled thread pool :" + Thread.currentThread().getId());
            }
        }, 1, 3, TimeUnit.SECONDS);
    }
运行结果:

new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
例子分析:延迟1秒开始,每隔3秒运行一次。


4.newSingleThreadExecutor 

    private void newSingleThreadPool() {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
            final int index = i;
            threadPool.execute(new Runnable() {

                @Override
                public void run() {
                    System.out.println("new single thread pool " + index + ":" +
                        Thread.currentThread().getId());
                }
            });
        }
    }
运行结果:

new single thread pool 0:9
new single thread pool 1:9
new single thread pool 2:9
new single thread pool 3:9
new single thread pool 4:9

例子分析:只有单线程,所以,每次只能执行一个线程,其余任务等待状态。


一般来说,CachedTheadPool在程序执行过程中通常会创建与所需数量相同的线程,然后在它回收旧线程时停止创建新线程,因此它是合理的Executor的首选,只有当这种方式会引发问题时(比如需要大量长时间面向连接的线程时),才需要考虑用FixedThreadPool。(该段话摘自《Thinking in Java》第四版)


线程池源码分析请看java-线程池(二)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章