目次
CountDownLatch
一般的な方法
使用例
何度も、同時タスクが存在します。依存関係の前後です。たとえば、データの詳細ページでは、データを取得するために複数のインターフェイスを同時に呼び出す必要があります。同時リクエストがデータを取得した後、結果をマージする必要があります。または、複数のデータ操作が完了した後、データ チェックが行われます。は必須です; これは実際には次のとおりです: 複数のスレッド (タスク) が完了した後、シナリオが要約され、マージされます。
本題に入りましょう
コードに直接移動します:
ホームページ Java &#&チュートリアル Java でマルチスレッドを使用して、メインスレッドが途中で終了しないようにするにはどうすればよいですか?

Java でマルチスレッドを使用して、メインスレッドが途中で終了しないようにするにはどうすればよいですか?

Apr 27, 2023 pm 04:40 PM
java

CountDownLatch

  • CountDownLatch (ロックとも呼ばれます) は、他のスレッドが一連の操作を完了するまで 1 つ以上のスレッドを待機できるようにする同期ヘルパー クラスです。 。

  • CountDownLatch 指定されたカウント値で初期化されます。 await メソッドは現在のカウント値 (count) になるまでブロックされます。countDown メソッドの呼び出しが 0 に達するため、カウントが 0 になると待機中のスレッドはすべて解放され、それ以降の await メソッドの呼び出しはすぐに戻ります。

構築方法:

//参数count为计数值
public CountDownLatch(int count) {};
ログイン後にコピー

一般的な方法

// 调用 await() 方法的线程会被挂起,它会等待直到 count 值为 0 才继续执行
public void await() throws InterruptedException {};
 
// 和 await() 类似,若等待 timeout 时长后,count 值还是没有变为 0,不再等待,继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {};
 
// 会将 count 减 1,直至为 0
public void countDown() {};
ログイン後にコピー

使用例

  • 最初は、インスタンス CountDownLatch countDown = new CountDownLatch(2);

  • 同期する必要があるスレッドが実行された後、カウントは -1、countDown.countDown();

  • 実行前に他のスレッドの実行が完了するのを待つ必要があるスレッドの場合は、countDown.await() を呼び出してブロック同期を実現します。 ############次のように。

  • アプリケーション シナリオ

  • CountDownLatch は通常、マルチスレッドのカウントダウン カウンターとして使用され、別のタスク セット (初期化) の実行が完了するまで待機させます。 CountDownLatch の決定)。

CountDownLatch の 2 つの使用シナリオ:

複数のスレッドを待機させ、同時実行をシミュレートします。

  • 単一スレッドを待機させ、複数のスレッド (タスク) が完了したら、要約してマージします。

  • シナリオ 1: 同時実行性のシミュレーション

    import java.util.concurrent.CountDownLatch;
     
    /**
     * 让多个线程等待:模拟并发,让并发线程一起执行
     */
    public class CountDownLatchTest {
        public static void main(String[] args) throws InterruptedException {
     
            CountDownLatch countDownLatch = new CountDownLatch(1);
            
            for (int i = 0; i < 5; i++) {
                new Thread(() -> {
                    try {
                        // 等待
                        countDownLatch.await();
                        String parter = "【" + Thread.currentThread().getName() + "】";
                        System.out.println(parter + "开始执行……");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }).start();
            }
     
            Thread.sleep(2000);
           
            countDownLatch.countDown();
        }
    }
    ログイン後にコピー
  • シナリオ 2: 複数のスレッドが完了した後、要約してマージする

何度も、同時タスクが存在します。依存関係の前後です。たとえば、データの詳細ページでは、データを取得するために複数のインターフェイスを同時に呼び出す必要があります。同時リクエストがデータを取得した後、結果をマージする必要があります。または、複数のデータ操作が完了した後、データ チェックが行われます。は必須です; これは実際には次のとおりです: 複数のスレッド (タスク) が完了した後、シナリオが要約され、マージされます。

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
 
/**
 * 让单个线程等待:多个线程(任务)完成后,进行汇总合并
 */
public class CountDownLatchTest3 {
 
    //用于聚合所有的统计指标
    private static Map map = new ConcurrentHashMap();
    //创建计数器,这里需要统计4个指标
    private static CountDownLatch countDownLatch = new CountDownLatch(4);
 
    public static void main(String[] args) throws Exception {
 
        //记录开始时间
        long startTime = System.currentTimeMillis();
 
        Thread countUserThread = new Thread(() -> {
            try {
                System.out.println("正在统计新增用户数量");
                Thread.sleep(3000);//任务执行需要3秒
                map.put("userNumber", 100);//保存结果值
                System.out.println("统计新增用户数量完毕");
                countDownLatch.countDown();//标记已经完成一个任务
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread countOrderThread = new Thread(() -> {
            try {
                System.out.println("正在统计订单数量");
                Thread.sleep(3000);//任务执行需要3秒
                map.put("countOrder", 20);//保存结果值
                System.out.println("统计订单数量完毕");
                countDownLatch.countDown();//标记已经完成一个任务
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        Thread countGoodsThread = new Thread(() -> {
            try {
                System.out.println("正在商品销量");
                Thread.sleep(3000);//任务执行需要3秒
                map.put("countGoods", 300);//保存结果值
                System.out.println("统计商品销量完毕");
                countDownLatch.countDown();//标记已经完成一个任务
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        Thread countmoneyThread = new Thread(() -> {
            try {
                System.out.println("正在总销售额");
                Thread.sleep(3000);//任务执行需要3秒
                map.put("countMoney", 40000);//保存结果值
                System.out.println("统计销售额完毕");
                countDownLatch.countDown();//标记已经完成一个任务
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        
        //启动子线程执行任务
        countUserThread.start();
        countGoodsThread.start();
        countOrderThread.start();
        countmoneyThread.start();
 
        try {
            //主线程等待所有统计指标执行完毕
            countDownLatch.await();
            long endTime = System.currentTimeMillis();//记录结束时间
            System.out.println("------统计指标全部完成--------");
            System.out.println("统计结果为:" + map);
            System.out.println("任务总执行时间为" + (endTime - startTime) + "ms");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
 
    }
}
ログイン後にコピー

本題に入りましょう

for ループの代わりにマルチスレッドを使用してクエリ効率を向上させ、メインスレッドが早期に終了して他のスレッドでデータ エラーが発生するのを防ぎます

コードに直接移動します:

@Override
    public AppResponse getLocations() throws InterruptedException {
        List<GetLocationVO> vos = new ArrayList<>();
        vos = projectDao.getLocationOne();    
//      原来的代码
//        for (GetLocationVO vo : vos) {
//            List<LocationVO> children = projectDao.getLocationChildren(vo.getId());
//            vo.setChildren(children);
//        }
        //改造后的代码
        Thread(vos,10);
        return AppResponse.success("查询成功",vos);
    }
 
    //此处有加锁
    public synchronized void Thread(List<GetLocationVO> list, int nThread) throws InterruptedException {
        if (CollectionUtils.isEmpty(list) || nThread <= 0 || CollectionUtils.isEmpty(list)) {
            return;
        }
        CountDownLatch latch = new CountDownLatch(list.size());//创建一个计数器(大小为当前数组的大小,确保所有执行完主线程才结束)
        ExecutorService pool = Executors.newFixedThreadPool(nThread);//创建一个固定的线程池
        for (GetLocationVO vo : list) {
            pool.execute(() -> {
                //处理的业务
                List<LocationVO> children = projectDao.getLocationChildren(vo.getId());
                vo.setChildren(children);
                latch.countDown();
            });
        }
        latch.await();
        pool.shutdown();
    }
ログイン後にコピー

以上がJava でマルチスレッドを使用して、メインスレッドが途中で終了しないようにするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプ Java での日付までのタイムスタンプ Aug 30, 2024 pm 04:28 PM

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

See all articles