1 ThreadPoolTaskExecutor スレッド プール:
ThreadPoolTaskExecutor は、Java 独自のスレッド プール ThreadPoolExecutor に基づく Spring の二次カプセル化です。主な目的は、Spring フレームワーク システムでより便利にすることです。スレッド プールは Spring で使用されます。これは Spring のデフォルトのスレッド プールです。
2 ThreadPoolTaskExecutor を使用して、ioc
構成ファイル フォームに Bean を注入します。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
Configuration フォームを構成します。 :
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) 拒否ポリシー:
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 のスケジュールされたタスクを使用します
schedule(Runnable task,Trigger) schedule(Runnable task,Date)
scheduleWithFixedDelay(Runnable task,long delay)
scheduleAtFixedRate(Runnable task,long delay)
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; }); } }
(2)@Scheduled(fixedRate=5000) スケジュールされた実行、5秒ごとに実行
(3) @Scheduled(corn="002**?") カスタム実行、コーン式 Baidu、この実行方法は一般的に使用され、corn="002**?" は毎日午前 2 時にスケジュールされたタスクの実行を開始します
3 @Scheduled によって開始されたタスクはシングルスレッドであり、ブロックされやすいことに注意してください。
( 2) @Scheduled アノテーションと @Async アノテーションによりスケジュールされたタスクが有効になり、@Async("pool") でスレッド プールを指定します。スレッド プールが指定されていない場合は、Spring の SimpleAsyncTaskExecutor スレッド プールが使用されます。プールはタスクを実行するたびにスレッドを追加します。効率が低くなります。
4: Spring の非同期タスク
注:@ Scheduled アノテーションと @Async アノテーションによりスケジュールされたタスクが有効になり、@Async("pool") でスレッド プールを指定します。スレッド プールが指定されていない場合、Spring の SimpleAsyncTaskExecutor スレッド プールが使用されます。このスレッド プールは、タスクを実行するたびにスレッドを追加するため、非効率的ですが、@Async が単独で非同期タスクを開始する場合は、デフォルトのスレッド プールが使用されます。必要に応じてスレッド プールをカスタマイズすることをお勧めします。 .
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()); } }
@Bean("myPool") public Executor executor(){ return new ThreadPoolExecutor(// 自定义一个线程池 1, // coreSize 2, // maxSize 60, // 60s TimeUnit.SECONDS, new ArrayBlockingQueue<>(3) // 有界队列,容量是3个 , Executors.defaultThreadFactory() , new ThreadPoolExecutor.AbortPolicy()); }
以上がSpringboot 独自のスレッド プールを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。