Java和Spring中线程池创建方法

您所在的位置:网站首页 java创建线程的方法和区别 Java和Spring中线程池创建方法

Java和Spring中线程池创建方法

#Java和Spring中线程池创建方法| 来源: 网络整理| 查看: 265

一、线程池定义 1.JDK中线程池类图

Executor:父接口,所有线程池都实现了这个接口,里面有一个excute()方法用于执行线程

ExecutorService:线程池接口,继承自Executor接口,供了生命周期管理的方法,返回 Future 对象,可以返回执行完的结果

ThreadPoolExecutor:线程池的具体实现类,一般使用ThreadPoolExecutor创建线程池

 

2.创建线程池的工具类

Executors:线程池的工具类,用于创建线程池,返回ExecutorService类型的线程池

1)public static ExecutorService newFiexedThreadPool(int Threads) :创建固定数目线程的线程池

2)public static ExecutorService newCachedThreadPool():创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果没有可用的线程,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程

3)public static ExecutorService newSingleThreadExecutor():创建一个单线程化的Executor

4)public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize):调度型线程池

3.区别

1)Executor 接口定义了 execute()方法用来接收一个Runnable接口的对象,不接受返回的对象,而 ExecutorService 接口中的 submit()方法可以通过Future 对象接受Runnable和Callable接口的对象

2)ExecutorService 还提供用来控制线程池的方法。比如:调用 shutDown() 方法终止线程池

3)Executors 类提供工厂方法用来创建不同类型的线程池

4.线程池参数

corePoolSize:核心线程数

maximumPoolSize, //最大线程数

keepAliveTime:当线程数超过核心线程数,线程的最大存活时间

unit:keepAliveTime的时间单位

workQueue:阻塞队列

threadFactory: 创建线程的工厂

handler:拒绝策略

5.线程池执行顺序

1)当线程数小于 corePoolSize时,创建线程执行任务。

2)当线程数大于等于 corePoolSize并且 workQueue 没有满时,放入workQueue中

3)线程数大于等于 corePoolSize并且当 workQueue 满时,新任务新建线程运行,线程总数要小于 maximumPoolSize

4)当线程总数等于 maximumPoolSize 并且 workQueue 满了的时候执行 handler 的 rejectedExecution。也就是拒绝策略

6.拒绝访问策略

ThreadPoolExecutor默认有四个拒绝策略:

1、ThreadPoolExecutor.AbortPolicy() 直接抛出异常RejectedExecutionException

2、ThreadPoolExecutor.CallerRunsPolicy() 直接调用run方法并且阻塞执行

3、ThreadPoolExecutor.DiscardPolicy() 直接丢弃后来的任务

4、ThreadPoolExecutor.DiscardOldestPolicy() 丢弃在队列中队首的任务

当然可以自己继承RejectedExecutionHandler来写拒绝策略.

 

二、线程池使用方法 1.Java JDK创建线程池的方法-ThreadPoolExecutor

1)使用ThreadPoolExecutor创建线程池

API如下所示:

public ThreadPoolExecutor(int corePoolSize,  //核心线程数                           int maximumPoolSize, //最大线程数                           long keepAliveTime,   //当线程数超过核心线程数,线程的最大存活时间                           TimeUnit unit,        //keepAliveTime的时间单位                           BlockingQueue workQueue) //阻塞队列容量                           {      this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,          Executors.defaultThreadFactory(), defaultHandler); }

所在包:java.util.concurrent.*

2)代码实现:

3)结果展示:

 

2.Spring创建线程池方式-ThreadPoolTaskExecutor

所在包:package org.springframework.core.task;

创建线程池并注入spring容器,开启@EnableAsync注解方便后续使用它@Async异步化调用

 

@Configuration @EnableAsync public class BeanConfig {     @Bean     public ThreadPoolTaskExecutor taskExecutor() {         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();         // 设置核心线程数         executor.setCorePoolSize(5);         // 设置最大线程数         executor.setMaxPoolSize(10);         // 设置队列容量         executor.setQueueCapacity(20);         // 设置线程活跃时间(秒)         executor.setKeepAliveSeconds(60);         // 设置默认线程名称         executor.setThreadNamePrefix("hello-");         // 设置拒绝策略         executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());         // 等待所有任务结束后再关闭线程池         executor.setWaitForTasksToCompleteOnShutdown(true);         return executor;     } } 3.异步调用线程池线程方法-ThreadPoolTaskExecutor

1)代码处使用

需要使用@Autowired装配获取注入的线程池对象

  @Autowired   private ThreadPoolTaskExecutor executor; ​   /**     * 根据活动id获取指定活动,异步添加缓存操作     */   @RequestMapping("/test9")   public String testTaskExecutor() throws Throwable {       log.info("进入方法:");       //异步调用       executor.execute(() -> {           try {               log.info("进入异步方法:");               Thread.sleep(2000);               jedisClusterClient.getJedisCluster().set("test9:async", "test"); ​           } catch (InterruptedException e) {               e.printStackTrace();           }           System.out.println("异步执行添加缓存:" + jedisClusterClient.getJedisCluster().get("test9:async"));       });       log.info("方法执行完毕");       return "test";   }

执行结果:

可以看到异步执行是在方法执行完毕后才执行的,不是同步的,异步化成功

2)使用@Async注解异步调用

注意:@Async修饰的方法的实例必须注入spring容器中方能使用,代码如下:

异步方法使用@Async调用:

执行结果:

可以看到结果也是异步化调用



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3