一 线程池
二通用线程池
废话没有,见代码
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)方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。