线程一 不推荐
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
//执行业务逻辑
}
});
线程二
import com.google.common.util.concurrent.ThreadFactoryBuilder;
private static ExecutorService poolThreadFactory;
public static void main(String[] args) {
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
.setNameFormat("缓存").build();
poolThreadFactory = new ThreadPoolExecutor(2, 20, 1000, TimeUnit.MILLISECONDS, new SynchronousQueue<>(), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
poolThreadFactory.submit(new ThreadTask());
}
private static class ThreadTask implements Runnable {
@Override
public void run() {
//执行逻辑
}
}
注:SynchronousQueue自己实验会导致内存不足 替换成LinkedBlockingQueue可用
线程三:spring自带
1.配置文件中
# 异步线程配置
# 配置核心线程数
async.executor.thread.core_pool_size = 2
# 配置最大线程数
async.executor.thread.max_pool_size = 10
# 配置队列大小
async.executor.thread.queue_capacity = 100
#线程存活保持时间
async.executor.thread.keepSecond=30
# 配置线程池中的线程的名称前缀
async.executor.thread.name.prefix = async-service-
2.启动初始化
@Configuration
@EnableAsync
public class ExecutorConfig {
private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);
@Value("${async.executor.thread.core_pool_size}")
private int corePoolSize;
@Value("${async.executor.thread.max_pool_size}")
private int maxPoolSize;
@Value("${async.executor.thread.queue_capacity}")
private int queueCapacity;
@Value("${async.executor.thread.keepSecond}")
private int keepSecond;
@Value("${async.executor.thread.name.prefix}")
private String namePrefix;
@Bean(name = "asyncServiceExecutor")
public Executor asyncServiceExecutor() {
logger.info("start asyncServiceExecutor");
//在这里修改
ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(corePoolSize);
//配置最大线程数
executor.setMaxPoolSize(maxPoolSize);
//配置队列大小
executor.setQueueCapacity(queueCapacity);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix(namePrefix);
//线程存活保持时间
executor.setKeepAliveSeconds(keepSecond);
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
3.启动配置3
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.concurrent.ListenableFuture;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @Author: mark
* @Date: Created in 2019/11/5 4:20 PM
* @Description:
*/
public class VisiableThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
private static final Logger logger = LoggerFactory.getLogger(VisiableThreadPoolTaskExecutor.class);
private void showThreadPoolInfo(String prefix) {
ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();
if (null == threadPoolExecutor) {
return;
}
logger.info("{}, {},taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",
this.getThreadNamePrefix(),
prefix,
threadPoolExecutor.getTaskCount(),
threadPoolExecutor.getCompletedTaskCount(),
threadPoolExecutor.getActiveCount(),
threadPoolExecutor.getQueue().size());
}
@Override
public void execute(Runnable task) {
showThreadPoolInfo("1. do execute");
super.execute(task);
}
@Override
public void execute(Runnable task, long startTimeout) {
showThreadPoolInfo("2. do execute");
super.execute(task, startTimeout);
}
@Override
public Future<?> submit(Runnable task) {
showThreadPoolInfo("1. do submit");
return super.submit(task);
}
@Override
public <T> Future<T> submit(Callable<T> task) {
showThreadPoolInfo("2. do submit");
return super.submit(task);
}
@Override
public ListenableFuture<?> submitListenable(Runnable task) {
showThreadPoolInfo("1. do submitListenable");
return super.submitListenable(task);
}
@Override
public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
showThreadPoolInfo("2. do submitListenable");
return super.submitListenable(task);
}
}
4.使用
@Override
@Async("asyncServiceExecutor")
public void saveUserMessage(String content, String title, ChtUser user, String noticecontent) {
try {
messageServer.saveUserMessage(content, title, user, noticecontent);
} catch (Exception e) {
log.error("推送消息失败!,失败原因:{}", e);
}
}
缓存:利用ConcurrentHashMap实现
LocalCache cache = LocalCache.getInStance();
//存放值
cache.putValue(bookId, catalogList);
//获取值
List<TempBookCatalog> tempBookCatalogs = (List<TempBookCatalog>) cache.getValue(tempBookId);
import java.io.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class LocalCache {
//默认的缓存容量
private static int DEFAULT_CAPACITY = 1024;
//最大容量
private static int MAX_CAPACITY = 100000;
//默认过期时间
private static int DEFAULT_EXPIRETIME = 60*5;
//刷新缓存的频率
private static int MONITOR_DURATION = 2;
private static LocalCache localCache = new LocalCache();
//使用默认容量创建一个Map
private static ConcurrentHashMap<String, CacheEntity> cache = new ConcurrentHashMap<>(
DEFAULT_CAPACITY);
private LocalCache(){
}
public static LocalCache getInStance(){
return localCache;
}
/**
* 将key-value 保存到本地缓存并制定该缓存的过期时间
*
* @param key
* @param value
* @param expireTime 过期时间,如果是-1 则表示永不过期
* @return
*/
public boolean putValue(String key, Object value, int expireTime) {
return putCloneValue(key, value, expireTime);
}
public boolean putValue(String key, Object value) {
return putCloneValue(key, value, DEFAULT_EXPIRETIME);
}
/**
* 将值通过序列化clone 处理后保存到缓存中,可以解决值引用的问题
*
* @param key
* @param value
* @param expireTime
* @return
*/
private boolean putCloneValue(String key, Object value, int expireTime) {
try {
if (cache.size() >= MAX_CAPACITY) {
return false;
}
// 序列化赋值
CacheEntity entityClone = clone(new CacheEntity(value, System.nanoTime(), expireTime));
cache.put(key, entityClone);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 序列化 克隆处理
*
* @param object
* @return
*/
private <T extends Serializable> T clone(T object) {
T cloneObject = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
cloneObject = (T) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return cloneObject;
}
/**
* 从本地缓存中获取key对应的值,如果该值不存则则返回null
*
* @param key
* @return
*/
public Object getValue(String key) {
return cache.get(key).getValue();
}
/**
* 清空所有
*/
public void clear() {
cache.clear();
}
/**
* 过期缓存的具体处理方法
*
* @throws Exception
*/
public void checkTime() {
//"开始处理过期 ";
for (String key : cache.keySet()) {
CacheEntity tce = cache.get(key);
long timoutTime = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime()
- tce.getGmtModify());
if (tce.getExpire() > timoutTime) {
continue;
}
System.out.println(" 清除过期缓存 : " + key);
//清除过期缓存和删除对应的缓存队列
cache.remove(key);
}
}
public void clear(String key){
cache.remove(key);
}
}
import java.io.Serializable;
public class CacheEntity implements Serializable{
private static final long serialVersionUID = -2416688868096254054L;
/**
* 值
*/
private Object value;
/**
* 保存的时间戳
*/
private long gmtModify;
/**
* 过期时间
*/
private int expire;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public long getGmtModify() {
return gmtModify;
}
public void setGmtModify(long gmtModify) {
this.gmtModify = gmtModify;
}
public int getExpire() {
return expire;
}
public void setExpire(int expire) {
this.expire = expire;
}
public CacheEntity(Object value, long gmtModify, int expire) {
super();
this.value = value;
this.gmtModify = gmtModify;
this.expire = expire;
}
}