私はJavaで非同期の利点を理解しようとしています。Java - 非同期 - スレッドプール
シナリオ1: 私は200
@Service
public class MyService{
public String execute(){
try {
//simulate blocking
Thread.sleep(3000);
} catch (InterruptedException e) {}
return "OK";
}
}
@RestController
public class MyController {
@Autowired
private MyService service;
@RequestMapping("/test")
public String test(){
return service.execute();
}
}
シナリオ2でのTomcat minとmaxのスレッドの両方を設定して、Tomcatにデプロイする春ブーツのWebアプリを、持っている:私は、Tomcatにデプロイする春ブーツのWebアプリを持っていますTomcatの最小値と最大値のスレッドそれぞれのシナリオで100
@Service
public class MyService{
public String execute(){
try {
//simulate blocking
Thread.sleep(3000);
} catch (InterruptedException e) {}
return "OK";
}
}
@RestController
public class MyController {
@Autowired
private MyService service;
private ExecutorService executorService = Executors.newFixedThreadPool(100);
@RequestMapping("/test")
public DeferredResult<String> test(){
DeferredResult<String> deferredResult = new DeferredResult<>();
CompletableFuture.supplyAsync(service::execute, executorService).
whenCompleteAsync((result, throwable) -> deferredResult.setResult(result));
return deferredResult;
}
}
に両方のセットで、スレッドの合計数は200
あるしかし、私はどのようにSCEN表示されません
シナリオ1では、400リクエストが同時に入力された場合、最初の200は200のHTTPスレッドによって処理され、次の200は3秒待たなければなりません)スレッドの1つが再び利用可能になるまで。
したがって、スループットは400秒/ 6秒= 66.6要求/秒でした。
平均応答時間は、(200×3 + 200×6)/(400)= 4.5秒シナリオ2では
、 400個の要求が同時に入ってきた場合でした。最初の100は100個のHTTPスレッドによってすぐに処理され、これらのスレッドはそれぞれサービスを呼び出し、結果を待つことなくすぐに再開し、次の100個の要求を処理できるようになります。 しかし、2番目の100の要求では、各HTTPスレッドがサービスを呼び出すときに、そのサービスは現在3秒(マイナス1秒)待って最初の100スレッドの処理を終了します。次の100は(executorerviceのスレッドプール内の)キューに入れられます。 ほとんどの場合、ほとんどすべてのリクエストが処理されましたが、 100がサービスで処理されています(3秒間待機中)。300は実行者サービスのスレッドプールに入れられます。 3秒後に、最初の100件が完了し、次に100件がデキューされ、処理されます。
そこでスループットは12秒で400のリクエスト=第
平均応答時間であった (100×3 + 100×6 + 100 * 9 * 12 + 100)/(400)= 7.5当たり33.3要求であります秒
「実行可能サービスのスレッドプール内のスレッド数を増やしてシナリオ2を改善することができます」というメッセージが返ってきました。これは、「うん、その後、私は風袋内のスレッド数を増やす同じ量だけシナリオ1のプール '
お返事ありがとうございます。 サービスが非同期であり、すぐに返された場合、完了可能な未来を完了するための応答を待っているスレッド –
APIの呼び出し側は、依然として「OK」応答を待っています。いくつかのスレッドは、たとえTomcatのhttpスレッドでなくても、その応答を返す必要があります。 –
@ jonathan.stiles - タイマータスクの時間が経過すると、タスクはスレッドプール上のアイドル状態のスレッドに割り当てられます。アイドル状態のスレッドがない場合、タスクはキューに割り当てられます。プールはアイドル状態になります。スレッドプールからのこのスレッドは、最終的にDeferredResultを完了し、その応答をクライアントに送信します。適切な非同期では、すべてのスレッドが作業を完了しているか、またはスケジュールされるのを待っているスレッドプール内でアイドル状態です。 – antlersoft