SpringBoot创建同步及异步线程池并定时记录线程池运行状态

一 线程池


二通用线程池

废话没有,见代码
MyThreadInfo :记录线程运行信息


import javax.persistence.Entity;
import lombok.Data;

@Entity(name="t_thread_info")
@Data
public class MyThreadInfo {
	//存活数量
	private int activeCount;
	//最大数量
	private int maxPoolSize;
	//当前线程池大小
	private int poolSize;
	//线程池基本大小
	private int corePoolSize;
	//队列长度
	private int queue_size;
	//可用队列长度
	private int avali_queue_size;
	//线程组名字
	private String threadGroupName;
	//服务器地址
	private String hostAddress;
	
}

ThreadPoolUtils 创建同步及异步线程池


import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.google.common.util.concurrent.ListeningExecutorService;

import com.google.common.util.concurrent.MoreExecutors;

@Configuration
public class ThreadPoolUtils {

    /**
     * 线程池维护线程的最少数量
     */
    private int corePoolSize = 10;                                                                       

    /**
     * 线程池维护线程的最大数量
     */
    private int maxPoolSize = 50;

    /**
     * 缓存队列
     */
    private int queueCapacity = 100;

    /**
     * 允许的空闲时间
     */
    private int keepAlive = 60;

    //同步线程池,如果不指定name值,则按methodName做beanName
    @Bean(name = "syncExceutor")
    public ThreadPoolTaskExecutor syncExceutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setKeepAliveSeconds(keepAlive);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("mqExecutor-");
         // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
        //对拒绝task的处理策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

    //异步线程池,如果不指定name值,则按methodName做beanName
    @Bean(name = "asyncExceutor")
    public AsyncTaskExecutor asyncExceutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setKeepAliveSeconds(keepAlive);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("mqExecutor-");
         // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
        //对拒绝task的处理策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
    
    
}

TaskQuart 定时任务,定时查询线程池运行状态及数据


import java.net.InetAddress;
import java.util.concurrent.ThreadPoolExecutor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;

import eureka.manager.entity.MyThreadInfo;

@Component
public class TaskQuart {

	@Autowired
	private ThreadPoolTaskExecutor syncExceutor;
	
	@Autowired
	private AsyncTaskExecutor asyncExceutor;
	
	@Scheduled(cron = "0/5 * * * * *")
	public void getThreadInfo(){
		InetAddress inte = null;
		try{
			inte = InetAddress.getLocalHost();
		}catch(Exception e){
			e.printStackTrace();
		}
		Object [] myThread = {syncExceutor,asyncExceutor};
		for(Object thread : myThread){
			MyThreadInfo info = new MyThreadInfo();
			ThreadPoolTaskExecutor threadTask = (ThreadPoolTaskExecutor)thread;
			//存活数量
			info.setActiveCount(threadTask.getActiveCount());
			//线程池基本大小
			info.setCorePoolSize(threadTask.getCorePoolSize());
			//最大数量
			info.setMaxPoolSize(threadTask.getMaxPoolSize());
			//当前线程池大小
			info.setPoolSize(threadTask.getPoolSize());
			
			//线程组名字
			ThreadGroup threadGroup = threadTask.getThreadGroup();
			info.setThreadGroupName(threadGroup.getName());
			
			ThreadPoolExecutor threadPoolExecutor = threadTask.getThreadPoolExecutor();
			//可用队列长度
			info.setAvali_queue_size(threadPoolExecutor.getQueue().remainingCapacity());
			//队列长度
			info.setQueue_size(threadPoolExecutor.getQueue().size());
			//服务器地址
			info.setHostAddress(inte.getHostAddress());
			
			System.out.println(JSONObject.toJSONString(info));
			
		}
	}
}

实现Runnable接口和Callable接口的区别

如果想让线程池执行任务的话需要实现的Runnable接口或Callable接口。

Runnable接口或Callable接口实现类都可以被ThreadPoolExecutor或ScheduledThreadPoolExecutor执行。

两者的区别在于 Runnable 接口不会返回结果但是 Callable 接口可以返回结果。

执行execute()方法和submit()方法的区别

1)execute() 方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否;

2)submit() 方法用于提交需要返回值的任务。线程池会返回一个Future类型的对象,通过这个Future对象可以判断任务是否执行成功,并且可以通过future的get()方法来获取返回值,get()方法会阻塞当前线程直到任务完成,而使用 get(long timeout,TimeUnit unit)方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值