【spring boot】13.在spring boot下使用多线程

时间:2021-10-08 23:20:20

使用场景:

方法处理到某一步,需要将信息交给另一个线程去处理!!

===================================================================================

第一种:最简单的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管理

【spring boot】13.在spring boot下使用多线程【spring boot】13.在spring boot下使用多线程
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;
    }

}
View Code

2.使用它

【spring boot】13.在spring boot下使用多线程【spring boot】13.在spring boot下使用多线程
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);
            }
        });

    }




}
View Code

 

====================================================================================================

第三种:使用spring封装的线程池

1.创建线程配置类【

@ComponentScan("com.sxd") 标明会在哪个包下使用多线程  

【spring boot】13.在spring boot下使用多线程【spring boot】13.在spring boot下使用多线程
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;
    }
}
View Code

2.创建线程任务执行类

【spring boot】13.在spring boot下使用多线程【spring boot】13.在spring boot下使用多线程
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;
    }
}
View Code

3.使用它

【spring boot】13.在spring boot下使用多线程【spring boot】13.在spring boot下使用多线程
@Component
public class Consumer1 {


    @Resource
    private AsyncTaskService asyncTaskService;


    public void test(String msg){
        System.out.println(Thread.currentThread().getName()+":"+msg);

        asyncTaskService.executeAsyncTask(msg);

    }
    
}
View Code

 

====================================================================================================

第四种:在代码中启动异步处理最简单的代码

public void test(){
    new Thread(()->doReplace(replaceLog)).start();         
}

public void doReplace(String replaceLog){
                  
            //异步处理的业务
}

 

======================================

就这么多,再补充噻!!