>  기사  >  Java  >  Springboot 자체 스레드 풀을 구현하는 방법

Springboot 자체 스레드 풀을 구현하는 방법

王林
王林앞으로
2023-06-28 16:33:05807검색

One: ThreadPoolTaskExecuto

1 ThreadPoolTaskExecutor 스레드 풀:

ThreadPoolTaskExecutor는 Java 자체 스레드 풀 ThreadPoolExecutor를 기반으로 하는 Spring의 보조 캡슐화입니다. 주요 목적은 Spring 프레임워크 시스템에서 스레드 풀을 더 편리하게 사용하도록 하는 것입니다. Spring 스레드 풀

2 ThreadPoolTaskExecutor를 사용하여 ioc에 빈 주입
구성 파일 형식, Spring이 자동으로 구성

## 默认线程池配置,ThreadPoolTaskExecutor 
# 核心线程数
spring.task.execution.pool.core-size=8  
# 最大线程数
spring.task.execution.pool.max-size=16
# 空闲线程存活时间
spring.task.execution.pool.keep-alive=60s
# 是否允许核心线程超时
spring.task.execution.pool.allow-core-thread-timeout=true
# 线程队列数量
spring.task.execution.pool.queue-capacity=100
# 线程关闭等待
spring.task.execution.shutdown.await-termination=false
spring.task.execution.shutdown.await-termination-period=
# 线程名称前缀
spring.task.execution.thread-name-prefix=demo_Thread

구성 형식:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledFuture;
//@Configuration
public class ThreadConfig {
    @Value("${task.maxPoolSize}")
    private int maxPoolSize;
    //todo 其他的相关配置都可以通过配置文件中注入
    @Bean("ThreadPoolTaskExecutor")
    public Executor myAsync() {
        final ThreadPoolTaskExecutor executor =
                new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(maxPoolSize);
        //todo  其他参数设置
        //初始化
        executor.initialize();
        return executor;
    }
}

3 스레드 생성 후 모든 스레드 풀을 ioc에서 가져옴

4 스레드 풀 처리 프로세스 :

(1) 코어 스레드 풀이 가득 찼는지 확인합니다. 그렇지 않은 경우 스레드를 생성하여 작업을 수행합니다. 코어 스레드 수가 가득 찼다면 작업 큐가 가득 찼는지 확인합니다. 작업 대기열이 가득 차면 최대 스레드 수를 확인하고, 스레드가 가득 차면 거부 정책에 따라 실행합니다.

(2) 거부 정책:

  • CallerRunsPolicy(): 원래 스레드 실행

  • AbortPolicy(): 직접 예외 발생

  • DiscardPolicy(): 직접 삭제

  • DiscardOldestPolicy(): 가장 오래된 작업 삭제 대기열

2: ThreadPoolTaskScheduler

1 ThreadPoolTaskScheduler는 정기적으로 작업 스레드 풀을 예약하여 비동기 작업을 처리합니다.

2 사용 방법: ThreadPoolTaskScheduler Bean 삽입

(1) 구성 파일 형식: ..
(2) 구성 클래스 형식:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledFuture;
@Configuration
public class ThreadPoolTaskSchedulerConfig {
    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
        final ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        //设置等待任务在关机时l候完成
        threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
        //设置等待时间为60s
        threadPoolTaskScheduler.setAwaitTerminationSeconds(60);
        return threadPoolTaskScheduler;
    }
}

3 ThreadPoolTaskScheduler 예약 작업 사용

일반 스레드 풀 사용 수행:

  • 제출(호출 가능), 결과 실행 필요

  • 제출(실행 가능), 실행 결과 필요 없음

(1) 예약된 작업

작업 내용 추가 실행 가능, 실행 주기 설정 트리거/날짜, 트리거 표현 Baidu는

 schedule(Runnable task,Trigger)
 schedule(Runnable task,Date)

(2) 간격 지정 작업 실행 시간, 시간 간격은 이전 작업 완료부터 시작까지입니다. 다음 작업, 밀리초

 scheduleWithFixedDelay(Runnable task,long delay)

(3) 고정된 빈도로 작업을 실행하고, 작업이 시작된 후 간격을 두고 새 작업을 실행하고, 마지막 작업이 완료되면 마지막 작업 실행이 완료된 후 다음 작업이 실행될 때까지 기다립니다. Completed

 scheduleAtFixedRate(Runnable task,long delay)

(4) 예약된 작업 취소:

예약된 작업 저장을 위한 컬렉션을 설정합니다. 예약된 작업 실행의 결과는 ScheduledFuture6b3d0130bba23ae47fe2b8e8cddf0195이며 컬렉션에 개체를 저장하고 ScheduledFuture<를 가져와 예약된 작업을 취소합니다. ;?> 컬렉션의 object.cancel(true)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.*;
@Service
public class SchedulerService {
    @Autowired
    ThreadPoolTaskScheduler scheduler;
    /**
     * 常规线程池使用
     */
    public void tesScheduler1() throws ExecutionException, InterruptedException {
        //无返回值
        final Future<?> demo_scheduler1 = scheduler.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("demo runnable scheduler");
            }
        });
        //无返回值
        final Future<?> demo_scheduler2 = scheduler.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                System.out.println("demo callable  scheduler");
                return "callable";
            }
        });
        System.out.println("result:" + demo_scheduler2.get());
    }
    /**
     * 定时任务
     */
    public void tesScheduler2() throws ParseException {
        //CronTrigger表达式百度即可
        scheduler.schedule(() -> {
            System.out.println("定时任务");
        }, new CronTrigger("0/1****?"));
        //创建指定时间的日期
        final Date date = new Date(2023, 3, 26, 21, 35);
        final DateFormat format = new SimpleDateFormat();
        final Date parse = format.parse("2023-03-26-21-26");
        scheduler.schedule(() -> {
            System.out.println(new Date());
        }, parse);
    }
    /**
     * 指定时间间隔执行任务,上次任务结束到下次任务开始的时间间隔
     */
    public void tesScheduler3() {
        scheduler.scheduleWithFixedDelay(() -> {
            //todo
        }, 300L);
    }
    /**
     * 固定频率执行任务,在固定一段时间后便会执行下次任务,
     * 如果时间到了上次任务还没执行完毕则等待,
     * 直到上一次任务执行完毕后立马执行下次任务
     */
    public void tesScheduler4() {
        scheduler.scheduleAtFixedRate(new FutureTask<String>(new Callable<String>() {
                    @Override
                    public String call() throws Exception {
                        return null;
                    }
                }),
                200);
    }
    //取消定时任务队列
    public static ConcurrentMap<String, ScheduledFuture> map = new ConcurrentHashMap<>();
    public void startTask(String k1) {
        map.compute(k1, (k, v) -> {
            if (map.containsKey(k)) return v;
            map.put(k, v);
            return v;
        });
    }
}

Three @Scheduled는 예약된 작업을 구현하고 주석은 예약된 작업을 활성화합니다

1 @EnableScheduled를 사용하여 지원을 활성화합니다

2 @Scheduled 주석 방법

(1 ) @Scheduled(fixedDelay=5000) 지연된 실행, 5초 후에 실행
(2) @Scheduled(fixedRate=5000) 예약된 실행, 5초마다 실행
(3) @Scheduled(corn="002* *?") 사용자 정의 실행 , corn 표현 Baidu, 이 실행 방법이 일반적으로 사용됩니다. corn="002**?"매일 오전 2시에 예약된 작업을 실행하기 시작합니다

3 @Scheduled로 시작한 작업은 단일 스레드이며, 쉬운 차단

(1) ThreadPoolTaskScheduler를 ioc에 삽입하면 Scheduled는 단일 스레드 차단 문제를 해결할 수 있는 ThreadPoolTaskScheduler 스레드 풀을 사용합니다.
(2) @Scheduled 및 @Async 주석은 @Async(" pool") 스레드 풀, 지정된 스레드 풀이 없으면 Spring의 SimpleAsyncTaskExecutor 스레드 풀이 사용됩니다. 이 스레드 풀은 매번 작업을 실행하기 위해 스레드를 추가하므로 비효율적입니다. 4: Spring의 비동기 작업

1 @ EnableAsync는 비동기 지원을 켭니다.

2 @Async는 비동기 작업을 활성화하고 스레드 풀을 지정합니다


참고: @Scheduled 및 @Async 주석은 예약된 작업을 활성화하고 스레드 풀이 아닌 경우 @Async("pool")에 스레드 풀을 지정합니다. 지정하면 Spring의 SimpleAsyncTaskExecutor 스레드 풀이 사용됩니다. 이 스레드 풀은 매번 작업을 실행하기 위해 스레드를 추가하므로 비효율적입니다. 그러나 @Async가 비동기 작업을 별도로 활성화하면 기본 스레드 풀이 사용됩니다. 필요에 따라 스레드 풀을 사용자 정의하는 것이 좋습니다. 참고: @Async의 반환 값은 void 또는 Future일 수 있으며 호출자와 @Async는 동일한 클래스에 있을 수 없습니다. 그렇지 않으면 aop가 사용되지 않습니다. : 사용자 정의 Java 스레드 풀 제시:

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncService {
    @Async
    public void showThreadName1() {
        //默认线程池
        System.out.println(Thread.currentThread().getName());
    }
    @Async("myPool")//指定线程池
    public void showThreadName2() {
        System.out.println(Thread.currentThread().getName());
    }
}

java 자체 스레드 풀, 캐시, 고정 수, 단일 스레드, 시간 제한,,,, 6~7가지 유형, 나중에 계속됨

위 내용은 Springboot 자체 스레드 풀을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제