Java

线程池使用场景

2021-09-09  本文已影响0人  芝兰之室也

Java提供四种线程池,分别对应不同的应用场景

考虑多线程因素:

任务数、任务执行时间、线程数、CPU核数

1、newCachedThreadPool

创建一个线程池,如果线程池中的线程数量过大,它可以有效的回收多余的线程,如果线程数不足,那么它可以创建新的线程。

代码示例:

        ExecutorService cachePool = Executors.newCachedThreadPool();
        for(int i=0;i<5;i++){
            cachePool.execute(() -> {
                System.out.println(Thread.currentThread().getName());
            });
        }

输出:每个任务都会起一个线程,无限扩大

pool-1-thread-1
pool-1-thread-2
pool-1-thread-3
pool-1-thread-4
pool-1-thread-5

2、newFixedThreadPool

代码示例:

        ExecutorService fixedPool = Executors.newFixedThreadPool(3);
        for(int i=0; i<5; i++){
            fixedPool.execute(() -> {
                System.out.println(Thread.currentThread().getName());
            });
        }

输出:

pool-2-thread-1
pool-2-thread-3
pool-2-thread-1
pool-2-thread-2
pool-2-thread-3

固定线程池大小为3,需要5个线程,所以前3个线程就存在线程复用的情况。

当任务执行存在时延时,前三个线程就不会出现线程复用的情况了:

        ExecutorService fixedPool = Executors.newFixedThreadPool(3);
        for(int i=0; i<5; i++){
            fixedPool.execute(() -> {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+":"+System.currentTimeMillis()/1000);
            });
        }

输出:任务耗时一秒,前三个线程没有复用

pool-1-thread-3:1631157921
pool-1-thread-1:1631157921
pool-1-thread-2:1631157921
pool-1-thread-1:1631157922
pool-1-thread-2:1631157922

3、ScheduledThreadPool

代码示例:

(1)定时任务:scheduleAtFixedRate

  • 表示上一个任务开始和下一个任务开始之间,间隔一个period;
  • 如果上一个任务执行完毕,则当前任务立即执行,如果上一个任务没有执行完毕,则需要等上一个任务执行完毕后立即执行。

a)任务执行时间小于period,则以period定时处理任务

ScheduledExecutorService schedPool = Executors.newScheduledThreadPool(3);
for (int i = 0; i < 3; i++) {
    schedPool.scheduleAtFixedRate(() ->{
        System.out.println(Thread.currentThread().getName()+":"+System.currentTimeMillis()/1000);
    }, 0,3, TimeUnit.SECONDS);

}

输出:

pool-1-thread-1:1631176308
pool-1-thread-1:1631176308
pool-1-thread-1:1631176308

pool-1-thread-1:1631176311
pool-1-thread-3:1631176311
pool-1-thread-1:1631176311

pool-1-thread-3:1631176314
pool-1-thread-1:1631176314
pool-1-thread-2:1631176314

b)若任务执行时间大于period,则以执行时间定时处理任务

ScheduledExecutorService schedPool = Executors.newScheduledThreadPool(3);
for (int i = 0; i < 3; i++) {
    schedPool.scheduleAtFixedRate(() ->{
        System.out.println(Thread.currentThread().getName()+":"+System.currentTimeMillis()/1000);
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }, 0,3, TimeUnit.SECONDS);
}

输出:

pool-1-thread-2:1631176413
pool-1-thread-3:1631176413
pool-1-thread-1:1631176413

pool-1-thread-2:1631176417
pool-1-thread-1:1631176417
pool-1-thread-3:1631176417

pool-1-thread-3:1631176421
pool-1-thread-2:1631176421
pool-1-thread-1:1631176421

(2)延时任务:scheduleWithFixedDelay

  • 表示上一个任务结束和下一个任务开始之间,时间间隔为一个delay

任务执行时间为4秒,延时为3秒,所以每个任务之间间隔7秒

ScheduledExecutorService schedPool = Executors.newScheduledThreadPool(3);
for (int i = 0; i < 3; i++) {
    schedPool.scheduleWithFixedDelay(() ->{
        System.out.println(Thread.currentThread().getName()+":"+System.currentTimeMillis()/1000);
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }, 0,3, TimeUnit.SECONDS);
}

输出:

pool-1-thread-1:1631176156
pool-1-thread-3:1631176156
pool-1-thread-2:1631176156

pool-1-thread-3:1631176163
pool-1-thread-1:1631176163
pool-1-thread-2:1631176163

pool-1-thread-1:1631176170
pool-1-thread-2:1631176170
pool-1-thread-3:1631176170

4、 SingleThreadExecutor

上一篇 下一篇

猜你喜欢

热点阅读