线程池---Executors类创建线程池

25 篇文章 0 订阅
Executors静态工厂创建几种常用线程池
  • Executors类:
    提供工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口;
1.创建了一个固定线程数量的线程池,可以控制线程最大并发数,超出的线程会在队列中等待。
它是一个典型且优秀的线程池,它具有线程池提高程序效率和节省创建线程时所耗的开销的优点。但是在线程池空闲时,即线程池中没有可运行任务时,它也不会释放工作线程,还会占用一定的系统资源。
newFixedThreadPool(int nThreads)

//线程池中线程数量是要指定传入的,注意在固定大小的线程池中使用的阻塞队列是LinkedBlockingQueue,无界阻塞队列。
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>(),
                                      threadFactory);
    }

2.创建了一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有的任务按照指定的顺序(FIFO, LIFO, 优先级)来执行的。
初始化的线程池中只有一个线程,如果该线程异常结束,会重新创建一个新的线程继续执行任务,唯一的线程可以保证所提交任务的顺序执行,内部使用LinkedBlockingQueue作为阻塞队列
newSingleThreadExecutor()
//核心线程数和最大线程数都为1    
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
    public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>(),
                                    threadFactory));
    }

3.创建了一个可缓存的线程池,如果线程池的长度超过处理需要,它可灵活回收空闲线程,若无可回收,则新建线程。   

默认存活时间60秒,线程池的线程数可达到Integer.MAX_VALUE,即2147483647,内部使用SynchronousQueue作为阻塞队列;新增一个任务即有一个线程处理,或者复用之前空闲的线程,或者重亲启动一个线程,但是一旦一个线程在60秒内一直处于等待状态时(也就是一分钟无事可做),则会被终止

在没有任务执行时,当线程的空闲时间超过keepAliveTime,则工作线程将会终止,当提交新任务时,如果没有空闲线程,则创建新线程执行任务,会导致一定的系统开销
newCachedThreadPool()
    
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>(),
                                      threadFactory);
    }

4.创建了一个单线程的定时任务调度线程池 
newSingleThreadScheduledExecutor()
    
    public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1));
    }
    public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1, threadFactory));
    }

5.创建了一个定长线程池,支持定时及周期性的任务执行。(定时调度线程池)
初始化的线程池可以在指定的时间内周期性的执行所提交的任务,在实际的业务场景中可以使用该线程池定期的同步数据。
newScheduledThreadPool(int corePoolSize)
    
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    public static ScheduledExecutorService newScheduledThreadPool(
            int corePoolSize, ThreadFactory threadFactory) {
        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
    }
  • Demo实例:
    (1)newFixedThreadPoolDemo:
public static void newFixedThreadPoolDemo(){
        //创建一个固定长度的线程池,一次执行固定长度的线程,之后按照程序继续执行
        ExecutorService fixedthreadpool = Executors.newFixedThreadPool(5);
        System.out.println("fixedthreadpool is starting");
        for (int i = 0; i < 15; i++) {
            final int count = i ;
            fixedthreadpool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(count +" " +Thread.currentThread().getName());
                }
            });
        }
        //shutdown方法只是发出了停止信号,
        // 等所有线程执行完毕会关闭线程池;而shutdownNow则是立即停止所有任务。
        fixedthreadpool.shutdown();
    }
fixedthreadpool is starting
1 pool-1-thread-2
5 pool-1-thread-2
6 pool-1-thread-2
7 pool-1-thread-2
8 pool-1-thread-2
9 pool-1-thread-2
10 pool-1-thread-2
0 pool-1-thread-1
11 pool-1-thread-2
13 pool-1-thread-2
14 pool-1-thread-2
12 pool-1-thread-1
3 pool-1-thread-4
2 pool-1-thread-3
4 pool-1-thread-5

 这是创建一个指定数量线程的线程池,使用newFixedThreadPool方法传入5个线程个数,从结果也可以看出是5个线程在并发执行,注意返回类型是ExecutorService。还使用了execute()方法提交线程。
(2)newSingleThreadExecutorDemo:

//创建单线程的线程池,一个一个线程的执行
    public static void newSingleThreadExecutorDemo(){
        ExecutorService singlethreadpool = Executors.newSingleThreadExecutor();
        System.out.println("singlethreadpool is starting");
        for (int i = 0; i < 10; i++) {
            final int count = i ;
            singlethreadpool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println(count +" " +Thread.currentThread().getName());
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

在这里插入图片描述
 单线程的线程池,只有一个线程在执行。
(3)newCachedThreadPoolDemo:

//创建一个可缓存的线程池   当线程池长度超过所需要的长度,则会收起空闲线程
    public static void newCachedThreadPoolDemo(){
        ExecutorService cachedthreadpool = Executors.newCachedThreadPool();
        System.out.println("cachedthreadpool is starting");
        for (int i = 0; i < 100; i++) {
            final int count = i ;
            cachedthreadpool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println(count + " " + Thread.currentThread().getName());
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

在这里插入图片描述(4)newSecheduledThreadPoolDemo:

//周期性的
    public static void newSecheduledThreadPoolDemo() {
        ExecutorService secheduledthreadpool = Executors.newScheduledThreadPool(5);
        System.out.println("secheduledthreadpool is starting");
                ((ScheduledExecutorService) secheduledthreadpool).schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("延时执行");
            }
        }, 3, TimeUnit.SECONDS);

方法注意:
ScheduledExecutorService#scheduleAtFixedRate()指的是“以固定的频率”执行,period(周期)指的是两次成功执行之间的时间;
ScheduledExecutorService#scheduleWithFixedDelay() 指的是“以固定的延时”执行,delay(延时)指的是一次执行终止和下一次执行开始之间的延迟;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java多模块项目中共用一个线程池配置,可以将线程池配置代码写在一个公共的工具中,然后在各个模块中调用该工具即可。 具体实现步骤如下: 1.创建一个公共的线程池配置工具Configure,例如: ```java public class Configure { private static final int CORE_POOL_SIZE = 10; private static final int MAX_POOL_SIZE = 10; private static final long KEEP_ALIVE_TIME = 0L; private static final TimeUnit TIME_UNIT = TimeUnit.MILLISECONDS; private static final BlockingQueue<Runnable> WORK_QUEUE = new LinkedBlockingQueue<>(); private static final ThreadPoolExecutor executorService = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TIME_UNIT, WORK_QUEUE); static { executorService.allowCoreThreadTimeOut(true); } public static ThreadPoolExecutor getExecutorService() { return executorService; } } ``` 2.在需要使用线程池的模块中,调用该工具获取线程池对象,例如: ```java public class MyModule { private static ThreadPoolExecutor executorService = Configure.getExecutorService(); public void doSomething() { executorService.execute(new Runnable() { @Override public void run() { // 执行线程任务 } }); } } ``` 通过上述方式,不同的模块均可共用同一个线程池配置,实现代码复用和统一管理。注意,使用ThreadPoolExecutor相较于Executors创建线程池,可以更加灵活地配置线程池参数。此外,在Configure中添加了static代码块来进行线程池的初始化操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值