検索
ホームページJava&#&チュートリアルJava マルチスレッド同時プログラミングはデータ処理効率をどの程度向上させますか?

    作業シナリオでは、ホストの IP アドレスに基づいて他のモデルの関連情報を更新するという要件に遭遇しました。要件は非常にシンプルで、一般的なデータベース連携のクエリと更新操作のみを必要としますが、コーディング実装の過程で、ホストの数が多いため、クエリと更新のループに長い時間がかかることが判明しました。インターフェイスを 1 回呼び出すのに約 30 ~ 40 秒かかります。操作が完了するまでの分時間。

    したがって、インターフェイス メソッドの実行時間を効果的に短縮するには、マルチスレッド同時プログラミング手法の使用、マルチコア プロセッサの並列実行機能の活用、データの非同期処理を検討してください。実行時間を短縮し、効率を向上させます。

    ここでは、固定数のスレッドを持つ再利用可能なスレッド プール FixedThreadPool が使用され、CountDownLatch 同時実行ツール クラスによって提供される同時プロセス制御ツールが併用されます。マルチスレッドの同時実行性を確保するため プログラミング中の通常の操作:

    • 最初に、Runtime.getRuntime() を通じて実行中のマシンの CPU スレッドを取得します。 availableProcessors() メソッド Number。その後、固定スレッド プール内のスレッド数を設定するために使用されます。

    • 2 番目に、 タスクの特性を決定します。計算負荷の高いタスクの場合は、スレッド数を CPU スレッド番号 1# に設定します。 ##、IO の場合、集中的なタスクの場合、スレッド数を 2 * CPU スレッドの数 に設定します。この方法ではデータベースと頻繁に対話する必要があるため、IO 集中型のタスクになります。

    • その後、データがグループ化されて切り取られます。各スレッドは 1 つのグループ化されたデータを処理します。グループ化されたグループの数はスレッドの数と一致し、オブジェクト CountDownLatch はコンストラクターを呼び出し、初期化パラメーター値はスレッドの数であり、メイン スレッドはすべての子スレッドの実行が完了するまで待機してから後続の操作を実行します。

    • 次に、

      executorService.execute() メソッドを呼び出し、run メソッドを書き換えてビジネス ロジックを記述します。データ処理コードでは、現在のスレッドの実行後にカウンターを 1 ずつデクリメントすることを忘れないでください。 最後に、すべてのサブスレッドが完了したら、スレッド プールを閉じます。

    • 作業シナリオでビジネス ロジック コードを省略した後の一般的な処理方法の例は次のとおりです。
    public ResponseData updateHostDept() {
    		// ...
    		List<Map> hostMapList = mongoTemplate.find(query, Map.class, "host");
            // split the hostMapList for the following multi-threads task
            // return the number of logical CPUs
            int processorsNum = Runtime.getRuntime().availableProcessors();
            // set the threadNum as 2*(the number of logical CPUs) for handling IO Tasks,
            // if Computing Tasks set the threadNum as (the number of logical  CPUs) + 1
            int threadNum = processorsNum * 2;  
            // the number of each group data 
            int eachGroupNum = hostMapList.size() / threadNum; 
            List<List<Map>> groupList = new ArrayList<>();
            for (int i = 0; i < threadNum; i++) {
                int start = i * eachGroupNum;
                if (i == threadNum - 1) {
                    int end = mapList.size();
                    groupList.add(hostMapList.subList(start, end));
                } else {
                    int end = (i+1) * eachGroupNum;
                    groupList.add(hostMapList.subList(start, end));
                }
            }
            // update data by using multi-threads asynchronously
            ExecutorService executorService = Executors.newFixedThreadPool(threadNum/2);
            CountDownLatch countDownLatch = new CountDownLatch(threadNum);
            for (List<Map> group : groupList) {
                executorService.execute(()->{
                    try {
                        for (Map map : group) {
                        	// update the data in mongodb
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                    	// let counter minus one 
                        countDownLatch.countDown();  
                    }
                });
            }
            try {
            	// main thread donnot execute until all child threads finish
                countDownLatch.await();  
            } catch (Exception e) {
                e.printStackTrace();
            }
            // remember to shutdown the threadPool
            executorService.shutdown();  
            return ResponseData.success();
    }

    次に、マルチスレッドの非同期更新戦略を使用した後、インターフェイスの呼び出しに必要なおおよその時間が

    30-40 min

    から 8-10 min に短縮され、実行効率が大幅に向上しました。

    ここでスレッド プールの作成に使用される
    newFixedThreadPool

    には、ブロッキング キューのデフォルトが無制限のキューになり、デフォルト値が であるという欠陥があることに注意してください。 Integer.MAX_VALUE は OOM 問題を引き起こす可能性が非常に高くなります。したがって、通常は ThreadPoolExecutor を使用してスレッド プールを作成し、待機キュー内のスレッドの数を指定して OOM 問題を回避できます。

    public ResponseData updateHostDept() {
    		// ...
    		List<Map> hostMapList = mongoTemplate.find(query, Map.class, "host");
            // split the hostMapList for the following multi-threads task
            // return the number of logical CPUs
            int processorsNum = Runtime.getRuntime().availableProcessors();
            // set the threadNum as 2*(the number of logical CPUs) for handling IO Tasks,
            // if Computing Tasks set the threadNum as (the number of logical  CPUs) + 1
            int threadNum = processorsNum * 2;  
            // the number of each group data 
            int eachGroupNum = hostMapList.size() / threadNum; 
            List<List<Map>> groupList = new ArrayList<>();
            for (int i = 0; i < threadNum; i++) {
                int start = i * eachGroupNum;
                if (i == threadNum - 1) {
                    int end = mapList.size();
                    groupList.add(hostMapList.subList(start, end));
                } else {
                    int end = (i+1) * eachGroupNum;
                    groupList.add(hostMapList.subList(start, end));
                }
            }
            // update data by using multi-threads asynchronously
            ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 8, 30L, TimeUnit.SECONDS, 
                    new ArrayBlockingQueue<>(100));
            CountDownLatch countDownLatch = new CountDownLatch(threadNum);
            for (List<Map> group : groupList) {
                executor.execute(()->{
                    try {
                        for (Map map : group) {
                        	// update the data in mongodb
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                    	// let counter minus one 
                        countDownLatch.countDown();  
                    }
                });
            }
            try {
            	// main thread donnot execute until all child threads finish
                countDownLatch.await();  
            } catch (Exception e) {
                e.printStackTrace();
            }
            // remember to shutdown the threadPool
            executor.shutdown();  
            return ResponseData.success();
    }

    上記のコードでは、コア スレッドの数とスレッドの最大数はそれぞれ 5 と 8 ですが、大きな値に設定すると、あまり大きな値には設定されません。コンテキストの切り替えにより時間の消費も増加しますが、マルチスレッドの利点を最大限に活用することはできません。適切なパラメータをどのように選択するかについては、マシンのパラメータとタスクの種類に基づいて決定する必要があります。

    最後に、コーディング以外の方法でマシンの CPU スレッド数を取得する場合も非常に簡単です。Windows システムでは、タスク マネージャーを通じて CPU スレッド数を確認できます。

    Java マルチスレッド同時プログラミングはデータ処理効率をどの程度向上させますか? 上の図からわかるように、私のマシンのコアは 8 個の CPU ですが、物理コアは 1 個です。 CPU コアは、ハイパースレッディング テクノロジを通じて 2 つの論理 CPU スレッドにシミュレートできるため、私のマシンは 8 コアと 16 スレッドをサポートします。

    以上がJava マルチスレッド同時プログラミングはデータ処理効率をどの程度向上させますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明
    この記事は亿速云で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
    高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?Mar 17, 2025 pm 05:46 PM

    この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

    適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?Mar 17, 2025 pm 05:45 PM

    この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。

    カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?Mar 17, 2025 pm 05:44 PM

    この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

    キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?Mar 17, 2025 pm 05:43 PM

    この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

    Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Mar 17, 2025 pm 05:35 PM

    Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します

    See all articles

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

    リアルなヌード写真を作成する AI 搭載アプリ

    AI Clothes Remover

    AI Clothes Remover

    写真から衣服を削除するオンライン AI ツール。

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    AI Hentai Generator

    AI Hentai Generator

    AIヘンタイを無料で生成します。

    ホットツール

    mPDF

    mPDF

    mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

    SAP NetWeaver Server Adapter for Eclipse

    SAP NetWeaver Server Adapter for Eclipse

    Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

    WebStorm Mac版

    WebStorm Mac版

    便利なJavaScript開発ツール

    MinGW - Minimalist GNU for Windows

    MinGW - Minimalist GNU for Windows

    このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

    VSCode Windows 64 ビットのダウンロード

    VSCode Windows 64 ビットのダウンロード

    Microsoft によって発売された無料で強力な IDE エディター