使用場景:
方法處理到某一步,需要將信息交給另一個線程去處理!!
===================================================================================
第一種:最簡單的Runnable
public void test(String msg){
System.out.println(Thread.currentThread().getName()+":"+msg);
Runnable runnable = dealMsg(msg);
//將返回的runnable對象傳入,並start()啟動線程
new Thread(runnable).start();
}
//創建一個Runnable,重寫run方法
public Runnable dealMsg(String msg){ Runnable runnable = new Runnable() { @Override public void run() { System.out.println("新開線程中處理:"+msg); } }; return runnable; }
====================================================================================================
第二種:自己創建JDK線程池,交給spring管理,然后將任務交給線程池即可
1.創建線程池,交給spring管理
package com.sxd.util;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Configuration
public class ThreadConfig {
/**
*newFixedThreadPool
創建一個指定工作線程數量的線程池。每當提交一個任務就創建一個工作線程,如果工作線程數量達到線程池初始的最大數,則將提交的任務存入到池隊列中。
newCachedThreadPool
創建一個可緩存的線程池。這種類型的線程池特點是:
1).工作線程的創建數量幾乎沒有限制(其實也有限制的,數目為Interger. MAX_VALUE), 這樣可靈活的往線程池中添加線程。
2).如果長時間沒有往線程池中提交任務,即如果工作線程空閑了指定的時間(默認為1分鍾),則該工作線程將自動終止。終止后,如果你又提交了新的任務,則線程池重新創建一個工作線程。
newSingleThreadExecutor
創建一個單線程化的Executor,即只創建唯一的工作者線程來執行任務,如果這個線程異常結束,會有另一個取代它,保證順序執行(我覺得這點是它的特色)。單工作線程最大的特點是可保證順序地執行各個任務,並且在任意給定的時間不會有多個線程是活動的 。
newScheduleThreadPool
創建一個定長的線程池,而且支持定時的以及周期性的任務執行,類似於Timer。
* @return
*/
@Bean
public ExecutorService getExecutorTools(){
ExecutorService executorService = Executors.newFixedThreadPool(8);
return executorService;
}
}
package com.sxd.util;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Configuration
public class ThreadConfig {
/**
*newFixedThreadPool
創建一個指定工作線程數量的線程池。每當提交一個任務就創建一個工作線程,如果工作線程數量達到線程池初始的最大數,則將提交的任務存入到池隊列中。
newCachedThreadPool
創建一個可緩存的線程池。這種類型的線程池特點是:
1).工作線程的創建數量幾乎沒有限制(其實也有限制的,數目為Interger. MAX_VALUE), 這樣可靈活的往線程池中添加線程。
2).如果長時間沒有往線程池中提交任務,即如果工作線程空閑了指定的時間(默認為1分鍾),則該工作線程將自動終止。終止后,如果你又提交了新的任務,則線程池重新創建一個工作線程。
newSingleThreadExecutor
創建一個單線程化的Executor,即只創建唯一的工作者線程來執行任務,如果這個線程異常結束,會有另一個取代它,保證順序執行(我覺得這點是它的特色)。單工作線程最大的特點是可保證順序地執行各個任務,並且在任意給定的時間不會有多個線程是活動的 。
newScheduleThreadPool
創建一個定長的線程池,而且支持定時的以及周期性的任務執行,類似於Timer。
* @return
*/
@Bean
public ExecutorService getExecutorTools(){
ExecutorService executorService = Executors.newFixedThreadPool(8);
return executorService;
}
}
2.使用它
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
@Component
public class Consumer1 {
@Resource
private ExecutorService executorService;
public void test(String msg){
System.out.println(Thread.currentThread().getName()+":"+msg);
/**
* 分類1:可以返回值的 Callable
*/
Future fal = executorService.submit(new Callable<String>() {
@Override
public String call() {
System.out.println(Thread.currentThread().getName()+":"+msg);
return "處理成功!";
}
});
try {
System.out.println(fal.get());
}catch (Exception e){
System.out.println(e);
}
/**
* 分類2:不會返回值的 Runnable
*/
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+msg);
}
});
/**
* 分類3:也可以這樣
*/
executorService.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+msg);
}
});
}
}
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
@Component
public class Consumer1 {
@Resource
private ExecutorService executorService;
public void test(String msg){
System.out.println(Thread.currentThread().getName()+":"+msg);
/**
* 分類1:可以返回值的 Callable
*/
Future fal = executorService.submit(new Callable<String>() {
@Override
public String call() {
System.out.println(Thread.currentThread().getName()+":"+msg);
return "處理成功!";
}
});
try {
System.out.println(fal.get());
}catch (Exception e){
System.out.println(e);
}
/**
* 分類2:不會返回值的 Runnable
*/
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+msg);
}
});
/**
* 分類3:也可以這樣
*/
executorService.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+msg);
}
});
}
}
====================================================================================================
第三種:使用spring封裝的線程池
1.創建線程配置類【
@ComponentScan("com.sxd") 標明會在哪個包下使用多線程
】
package com.sxd.util;
import java.util.concurrent.Executor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@ComponentScan("com.sxd")
@EnableAsync
// 線程配置類
public class AsyncTaskConfig implements AsyncConfigurer {
// ThredPoolTaskExcutor的處理流程
// 當池子大小小於corePoolSize,就新建線程,並處理請求
// 當池子大小等於corePoolSize,把請求放入workQueue中,池子里的空閑線程就去workQueue中取任務並處理
// 當workQueue放不下任務時,就新建線程入池,並處理請求,如果池子大小撐到了maximumPoolSize,就用RejectedExecutionHandler來做拒絕處理
// 當池子的線程數大於corePoolSize時,多余的線程會等待keepAliveTime長時間,如果無請求可處理就自行銷毀
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);// 最小線程數
taskExecutor.setMaxPoolSize(10);// 最大線程數
taskExecutor.setQueueCapacity(25);// 等待隊列
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
package com.sxd.util;
import java.util.concurrent.Executor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@ComponentScan("com.sxd")
@EnableAsync
// 線程配置類
public class AsyncTaskConfig implements AsyncConfigurer {
// ThredPoolTaskExcutor的處理流程
// 當池子大小小於corePoolSize,就新建線程,並處理請求
// 當池子大小等於corePoolSize,把請求放入workQueue中,池子里的空閑線程就去workQueue中取任務並處理
// 當workQueue放不下任務時,就新建線程入池,並處理請求,如果池子大小撐到了maximumPoolSize,就用RejectedExecutionHandler來做拒絕處理
// 當池子的線程數大於corePoolSize時,多余的線程會等待keepAliveTime長時間,如果無請求可處理就自行銷毀
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);// 最小線程數
taskExecutor.setMaxPoolSize(10);// 最大線程數
taskExecutor.setQueueCapacity(25);// 等待隊列
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
2.創建線程任務執行類
package com.sxd.util;
import java.util.Random;
import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
@Service
// 線程執行任務類
public class AsyncTaskService {
Random random = new Random();// 默認構造方法
@Async
// 表明是異步方法
// 無返回值
public void executeAsyncTask(String msg) {
System.out.println(Thread.currentThread().getName()+"開啟新線程執行" + msg);
}
/**
* 異常調用返回Future
*
* @param i
* @return
* @throws InterruptedException
*/
@Async
public Future<String> asyncInvokeReturnFuture(int i) throws InterruptedException {
System.out.println("input is " + i);
Thread.sleep(1000 * random.nextInt(i));
Future<String> future = new AsyncResult<String>("success:" + i);// Future接收返回值,這里是String類型,可以指明其他類型
return future;
}
}
package com.sxd.util;
import java.util.Random;
import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
@Service
// 線程執行任務類
public class AsyncTaskService {
Random random = new Random();// 默認構造方法
@Async
// 表明是異步方法
// 無返回值
public void executeAsyncTask(String msg) {
System.out.println(Thread.currentThread().getName()+"開啟新線程執行" + msg);
}
/**
* 異常調用返回Future
*
* @param i
* @return
* @throws InterruptedException
*/
@Async
public Future<String> asyncInvokeReturnFuture(int i) throws InterruptedException {
System.out.println("input is " + i);
Thread.sleep(1000 * random.nextInt(i));
Future<String> future = new AsyncResult<String>("success:" + i);// Future接收返回值,這里是String類型,可以指明其他類型
return future;
}
}
3.使用它
@Component
public class Consumer1 {
@Resource
private AsyncTaskService asyncTaskService;
public void test(String msg){
System.out.println(Thread.currentThread().getName()+":"+msg);
asyncTaskService.executeAsyncTask(msg);
}
}
@Component
public class Consumer1 {
@Resource
private AsyncTaskService asyncTaskService;
public void test(String msg){
System.out.println(Thread.currentThread().getName()+":"+msg);
asyncTaskService.executeAsyncTask(msg);
}
}
====================================================================================================
第四種:在代碼中啟動異步處理最簡單的代碼
public void test(){
new Thread(()->doReplace(replaceLog)).start();
}
public void doReplace(String replaceLog){
//異步處理的業務
}
======================================
就這么多,再補充噻!!

