使用场景:
方法处理到某一步,需要将信息交给另一个线程去处理!!
===================================================================================
第一种:最简单的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管理
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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.使用它
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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") 标明会在哪个包下使用多线程
】
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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.创建线程任务执行类
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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.使用它
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
@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){ //异步处理的业务 }
======================================
就这么多,再补充噻!!