一 線程池
二通用線程池
廢話沒有,見代碼
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;
//同步線程池
@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;
}
//異步線程池
@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)方法則會阻塞當前線程一段時間後立即返回,這時候有可能任務沒有執行完。