前言
***多线程***工作之中也是经常用到的,但是每次用的时候却总是忘了怎么使用,然后要去翻之前的代码,感觉太LOW了。今天做个总结吧!
springBoot之多线程使用
线程工具类
import java.util.concurrent.*;
/**
* @author yuer629
*
* 调用:
* PushThreadPools.exec.execute(() -> { //调用方法 });
*
*/
public class PushThreadPools {
//核心线程池大小
static final int corePoolSize = 5;
//最大线程池大小
static final int maximumPoolSize = 50;
//线程最大空闲时间
static final long keepAliveTime = 3000L;
//时间单位
static final TimeUnit unit = TimeUnit.MILLISECONDS;
public static ExecutorService exec = new ThreadPoolExecutor(
// 核心线程池大小
corePoolSize,
//最大线程池大小
maximumPoolSize,
//线程最大空闲时间
keepAliveTime,
//时间单位
unit,
//线程等待队列
new LinkedBlockingQueue<Runnable>(65),
//线程创建工厂
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r);
}
},
//拒绝策略,这里直接抛出异常
new ThreadPoolExecutor.AbortPolicy()
);
}
如果有不同的任务,就创建不同的线程工具类就行了。在需要异步操作的时候就可以直接使用了。
普通Java使用线程
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadPool {
public static int qa = 1;
public static void main(String[] args) throws Exception{
//创建有10个线程的线程池,将1000000次操作分10次添加到线程池
int threads = 10;
// ExecutorService就是Java中对线程池的实现
ExecutorService pool = Executors.newFixedThreadPool(threads);
// CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信
CountDownLatch latch = new CountDownLatch(threads);
// AtomicInteger原子操作类 incrementAndGet()自增计数
AtomicInteger n = new AtomicInteger(0);
int sum = 1000000;
for (int t = 0; t < threads; t++) {
pool.submit(() -> {
int value = n.incrementAndGet();
while (qa<sum){
System.out.println(qa+";"+value);
qa++;
}
latch.countDown();
});
}
//等待全部线程执行完成,打印执行时间
latch.await();
}
}
@Async
配置类:SpringBoot应用中需要添加@EnableAsync注解,来开启异步调用,一般还会配置一个线程池,异步的方法交给特定的线程池完成,如下:
@Configuration
@EnableAsync
public class AsyncConfiguration {
@Bean("httpExecutor")
public Executor doSomethingExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数:线程池创建时候初始化的线程数
executor.setCorePoolSize(10);
// 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
executor.setMaxPoolSize(20);
// 缓冲队列:用来缓冲执行任务的队列
executor.setQueueCapacity(500);
// 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
executor.setKeepAliveSeconds(60);
// 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
executor.setThreadNamePrefix("do-something-");
// 缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程)
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
executor.initialize();
return executor;
}
}
一般使用
public String something() {
int count = 10;
for (int i = 0; i < count; i++) {
doSomething("index = " + i);
}
return "success";
}
// 指定使用beanname为doSomethingExecutor的线程池
@Async("httpExecutor")
public String doSomething(String message) {
log.info("do something, message={}", message);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
log.error("do something error: ", e);
}
return message;
}
有返回值情况
// 异步请求
CompletableFuture<String> httpOne = okHttpPost1(header);
String vUrl = vaccineInoculateInfoUrl + "?idCard="+paraMap.get("userid");
String sUrl = selectNucleicAcidInfoUrl + "?idCard="+paraMap.get("userid");
CompletableFuture<String> httpTwo = httpPost(vUrl);
CompletableFuture<String> httpThree = httpPost(sUrl);
// 等待所有任务都执行完
CompletableFuture.allOf(httpOne, httpTwo, httpThree).join();
String res1 = httpOne.get();
String res2 = httpTwo.get();
String res3 = httpThree.get();
System.out.println("返回值:"+res1+";res2::"+res2+";res3::"+res3);
@Async("httpExecutor")
public CompletableFuture<String> okHttpPost1(Map<String,Object> params) throws InterruptedException {
System.out.println("异步操作okHttpPost1:"+System.currentTimeMillis());
String content = (String) params.get("content");
String res ="";
try {
res = OkHttpUtils.getInstance().httpPostText(codeInfoByIdcardUrl, params, content);
JSONObject resObj = JSONObject.parseObject(res);
if("1006".equals(resObj.getString("errorCode"))){
System.out.println("token过期,重新获取。");
expireTime = 0;
System.out.println("t2="+System.currentTimeMillis());
res = OkHttpUtils.getInstance().httpPostText(codeInfoByIdcardUrl, params, content);
resObj = JSONObject.parseObject(res);
}
} catch (IOException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture(res);
}
@Async("httpExecutor")
public CompletableFuture<String> httpPost(String url) throws InterruptedException {
System.out.println("异步操作:"+url+";;"+System.currentTimeMillis());
String res = "";
try {
res = HttpUtil.httpPost(url);
} catch (Exception e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture(res);
}