Springbootの非同期スレッドプール
4789 ワード
1:スレッドプールの定義コアスレッド数10:スレッドプール作成時に初期化するスレッド数 最大スレッド数20:スレッドプール最大スレッド数、バッファキューがいっぱいになった後にのみコアスレッド数を超えるスレッド を申請する.バッファキュー200:タスクを実行するためのキュー をバッファリングするスレッドのアイドル時間60秒:コアスレッドのアウトを超えるスレッドがアイドル時間に到達すると が破棄される.スレッドプール名の接頭辞:設定が完了すると、処理タスクが存在するスレッドプール を容易に特定できます.スレッドプールのタスク拒否処理ポリシー:ここでは は破棄されます.
説明:
2:スレッドプールの使用方法
3非同期タスクの実行
4注意事項
注意:@Async修飾関数はstaticタイプとして定義しないでください.これにより、非同期呼び出しは有効になりません.
異常メッセージ
@EnableAsync
@Configuration
class TaskPoolConfig {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(200);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("taskExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(
true
);
executor.setAwaitTerminationSeconds(
60
);
return executor;
}
}
ThreadPoolTaskExecutor
を使用してスレッドプールを作成し、次のパラメータを設定しました.CallerRunsPolicy
ポリシーを採用し、スレッドプールに処理能力がない場合、このポリシーはexecuteメソッドの呼び出しスレッドで拒否されたタスクを直接実行します.実行プログラムが終了すると、タスク説明:
setWaitForTasksToCompleteOnShutdown(true)
この方法は、スレッドプールが閉じられている間にすべてのタスクが完了してから他のBeanを破棄し続けるのを待つための鍵です.これにより、これらの非同期タスクの破棄はRedisスレッドプールの破棄よりも先になります.また、スレッドプール内のタスクの待ち時間を設定するsetawaitTerminationSeconds(60)も設定されており、この時点を超えても破棄されていない場合は強制的に破棄され、アプリケーションがブロックされるのではなく最後に閉じることができるようにしています.2:スレッドプールの使用方法
@Slf4j
@Component
public class Task {
public static Random random = new Random();
@Autowired
private
StringRedisTemplate stringRedisTemplate;
@Async("taskExecutor")
public void doTaskOne() throws Exception {
log.info(" ");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info(stringRedisTemplate.randomKey());
log.info(" , :" + (end - start) + " ");
}
@Async("taskExecutor")
public void doTaskTwo() throws Exception {
log.info(" ");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info(" , :" + (end - start) + " ");
}
@Async("taskExecutor")
public void doTaskThree() throws Exception {
log.info(" ");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info(" , :" + (end - start) + " ");
}
}
3非同期タスクの実行
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
private Task task;
@Test
public void test() throws Exception {
task.doTaskOne();
task.doTaskTwo();
task.doTaskThree();
Thread.currentThread().join();
}
}
2018-03-27 22:01:15.620 INFO 73703 --- [ taskExecutor-1] com.didispace.async.Task :
2018-03-27 22:01:15.620 INFO 73703 --- [ taskExecutor-2] com.didispace.async.Task :
2018-03-27 22:01:15.620 INFO 73703 --- [ taskExecutor-3] com.didispace.async.Task :
2018-03-27 22:01:18.165 INFO 73703 --- [ taskExecutor-2] com.didispace.async.Task : , :2545
2018-03-27 22:01:22.149 INFO 73703 --- [ taskExecutor-3] com.didispace.async.Task : , :6529
2018-03-27 22:01:23.912 INFO 73703 --- [ taskExecutor-1] com.didispace.async.Task : , :8292
4注意事項
注意:@Async修飾関数はstaticタイプとして定義しないでください.これにより、非同期呼び出しは有効になりません.
異常メッセージ
JedisConnectionException: Could not get a resource from the pool
から,アプリケーションが閉じている間に非同期タスクが実行されていることが容易に考えられるが,Redis接続プールが先に破棄されたため,非同期タスクでRedisにアクセスする操作が上記のエラーを報告した.だから、上記の実現方法はアプリケーションが閉じたときに優雅ではないと結論しました.では、私たちはどうすればいいのでしょうか.次のように設定します.executor.setWaitForTasksToCompleteOnShutdown(
true
);
executor.setAwaitTerminationSeconds(
60
);
:https://www.cnblogs.com/domi22/p/9418450.html