Spring Boot マルチスレッドの実際のアプリケーション シナリオとマルチスレッドのパフォーマンスを最適化する方法を紹介します。

Spring Boot は、Spring ベースのアプリケーションを迅速に作成して実行できるようにする人気の Java フレームワークです。Spring Boot での開発には、いくつかの実用的なアプリケーション シナリオと、マルチスレッドのパフォーマンスを最適化できるいくつかのテクニックがあります。このブログでは、一般的なシナリオとテクニックをいくつか紹介しますので、お役に立てれば幸いです。

実際の応用シナリオ

Spring Boot で開発する場合、外部 API の呼び出し、複雑な計算の実行、大量のデータの処理など、時間のかかるタスクを処理する必要がある場合があります。これらのタスクはメイン スレッドをブロックし、アプリケーションの応答性を低下させたり、タイムアウトやメモリ オーバーフローを引き起こしたりする場合があります。これらの問題を解決するには、マルチスレッドを使用してこれらのタスクを同時に実行し、アプリケーションの効率とパフォーマンスを向上させることができます。

外部APIを呼び出す

Spring Boot アプリケーションで外部 API を呼び出し、データを取得してデータベースに保存する必要があるとします。メインスレッドで API を直接呼び出す場合は、後続のロジックの実行を続ける前に API の応答を待つ必要があります。これはメインスレッドのリソースを無駄にし、ユーザーエクスペリエンスにも影響します。これを回避するには、@Asyncアノテーションを使用して非同期メソッドをマークし、別のスレッドで実行されるようにします。例えば:

@Service
public class ApiService {
    
    

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DataRepository dataRepository;

    @Async
    public void callApiAndSaveData() {
    
    
        // 调用外部的API
        Data data = restTemplate.getForObject("https://example.com/api", Data.class);
        // 保存数据到数据库
        dataRepository.save(data);
    }
}

上記のコードでは、@Serviceアノテーションを使用してサービス クラスを定義し、 2 つのコンポーネントApiServiceを挿入しますHTTPリクエストを送信するためのツールクラスであり、データベースを操作するためのインターフェースです。次に、メソッドを定義しアノテーションを使用してそれを非同期メソッドとしてマークします。このようにして、このメソッドを呼び出すと、メインスレッドをブロックせずに新しいスレッドで実行されます。RestTemplateDataRepositoryRestTemplateDataRepositorycallApiAndSaveData()@Async

注釈を使用するには@Async、Spring Boot アプリケーションで非同期サポートを有効にする必要もあります。これを実現するには、構成クラスにアノテーションを追加します@EnableAsync例えば:

@Configuration
@EnableAsync
public class AsyncConfig {
    
    
}

複雑な計算を実行する

Spring Boot アプリケーションで、大きな数の階乗の計算など、複雑な計算を実行する必要があるとします。メインスレッドで直接計算を実行する場合、後続のロジックの実行を続ける前に、計算結果を待つ必要があります。これはメインスレッドの CPU リソースを占有し、ユーザー エクスペリエンスにも影響します。これを回避するには、CompletableFutureクラスを使用して非同期タスクを作成し、将来の結果を返すことができます。例えば:

@Service
public class MathService {
    
    

    public CompletableFuture<BigInteger> factorial(BigInteger n) {
    
    
        // 创建一个异步任务
        return CompletableFuture.supplyAsync(() -> {
    
    
            // 执行复杂的计算
            BigInteger result = BigInteger.ONE;
            for (BigInteger i = BigInteger.ONE; i.compareTo(n) <= 0; i = i.add(BigInteger.ONE)) {
    
    
                result = result.multiply(i);
            }
            return result;
        });
    }
}

上記のコードでは、@Serviceアノテーションを使用してサービス クラスを定義しますMathServicefactorial()次に、パラメータとして大きな数値を受け取り、将来の結果を返すメソッドを定義します。このメソッドを使用してCompletableFuture.supplyAsync()非同期タスクを作成し、ラムダ式を渡して計算ロジックを定義しました。CompletableFutureこうすることで、このメソッドを呼び出すと、メインスレッドをブロックすることなく、すぐにオブジェクトが返されます。このオブジェクトのメソッドを他の場所で使用して計算結果を取得したり、計算結果を処理するコールバック関数を追加したりできます。例えば:

@Controller
public class MathController {
    
    

    @Autowired
    private MathService mathService;

    @GetMapping("/factorial")
    public String factorial(@RequestParam("n") BigInteger n, Model model) {
    
    
        // 调用异步方法
        CompletableFuture<BigInteger> future = mathService.factorial(n);
        // 添加回调函数
        future.thenAccept(result -> {
    
    
            // 将计算结果添加到模型中
            model.addAttribute("result", result);
        });
        // 返回视图名称
        return "factorial";
    }
}

上記のコードでは、@Controllerアノテーションを使用してコントローラー クラスを定義しMathControllerMathServiceコンポーネントを挿入します。factorial()次に、リクエスト パラメーターを受け取りn、ビュー名を返すメソッドを定義します。アノテーションを使用して@GetMapping、GET リクエストをこのメソッドにマップします。MathServiceこのメソッドでは、非同期メソッドを呼び出しfactorial()、将来の結果を取得しました。次に、CompletableFuture.thenAccept()メソッドを使用してラムダ式を受け入れるコールバック関数を追加し、処理ロジックを定義しました。このロジックでは、ビューに表示するために計算結果をモデルに追加します。

大量のデータを処理する

ファイルからデータを読み取り、分析や変換を実行するなど、Spring Boot アプリケーションで大量のデータを処理する必要があるとします。メインスレッドでデータを直接処理する場合、後続のロジックの実行を続ける前に、データ処理が完了するまで待つ必要があります。これはメインスレッドのメモリリソースを占有し、ユーザーエクスペリエンスにも影響します。これを回避するには、 を使用してStream API並列ストリームを作成し、マルチコア CPU を利用してデータ処理を高速化します。例えば:

@Service
public class DataService {
    
    

    public void processData(String fileName) {
    
    
        // 创建一个并行流
        try (Stream<String> lines = Files.lines(Paths.get(fileName)).parallel()) {
    
    
            // 对每一行数据进行分析和转换
            lines.map(line -> analyzeAndTransform(line))
                // 对转换后的数据进行汇总和输出
                .collect(Collectors.groupingBy(data -> data.getType(), Collectors.counting()))
                .forEach((type, count) -> System.out.println(type + ": " + count));
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    private Data analyzeAndTransform(String line) {
    
    
        // 省略具体的分析和转换逻辑
        return new Data();
    }
}

上記のコードでは、@Serviceアノテーションを使用してサービス クラスを定義しますDataServiceprocessData()次に、ファイル名をパラメータとして受け取るメソッドを定義します。このメソッドでは、Files.lines()ファイルから 1 行ずつデータを読み取ることができるストリームを作成するメソッドを使用しました。次に、Stream.parallel()メソッドを使用してストリームを並列ストリームに変換しました。これにより、複数のスレッドがストリーム内の要素を同時に処理できるようになります。次に、一連のストリーム操作を使用してデータの各行を分析および変換し、変換されたデータを要約して出力します。

マルチスレッドのパフォーマンスを最適化する方法

Spring Boot で開発する場合、マルチスレッドを使用するとアプリケーションの効率とパフォーマンスが向上しますが、注意しなければならない問題やリスクもいくつかあります。マルチスレッドが不適切に使用されると、デッドロック、競合状態、メモリ リークなどの問題が発生する可能性があります。これらの問題を回避し、マルチスレッドのパフォーマンスを最適化するには、いくつかの原則と手法に従うことができます。

おすすめ

転載: blog.csdn.net/m0_61581389/article/details/132595539