iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >java怎么使用多线程解决主线程提前结束问题
  • 470
分享到

java怎么使用多线程解决主线程提前结束问题

2023-07-05 11:07:46 470人浏览 薄情痞子
摘要

这篇文章主要介绍“java怎么使用多线程解决主线程提前结束问题”,在日常操作中,相信很多人在java怎么使用多线程解决主线程提前结束问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java怎么使用多线程解决

这篇文章主要介绍“java怎么使用多线程解决主线程提前结束问题”,在日常操作中,相信很多人在java怎么使用多线程解决主线程提前结束问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java怎么使用多线程解决主线程提前结束问题”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

CountDownLatch

  • CountDownLatch(也叫闭)是一个同步协助类,允许一个或多个线程等待,直到其他线程完成操作集。

  • CountDownLatch 使用给定的计数值(count)初始化。await 方法会阻塞直到当前的计数值(count)由于 countDown 方法的调用达到 0,count 为 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,直至为 0public void countDown() {};

使用案例

  • 首先是创建实例 CountDownLatch countDown = new CountDownLatch(2);

  • 需要同步的线程执行完之后,计数 -1, countDown.countDown();

  • 需要等待其他线程执行完毕之后,再运行的线程,调用 countDown.await()实现阻塞同步。

  • 如下。

应用场景

CountDownLatch 一般用作多线程倒计时计数器,强制它们等待其他一组(CountDownLatch的初始化决定)任务执行完成。

CountDownLatch的两种使用场景:

  • 让多个线程等待,模拟并发

  • 让单个线程等待,多个线程(任务)完成后,进行汇总合并。

场景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:多个线程完成后,进行汇总合并

很多时候,我们的并发任务,存在前后依赖关系;比如数据详情页需要同时调用多个接口获取数据,并发请求获取到数据后、需要进行结果合并;或者多个数据操作完成后,需要数据 check;这其实都是:在多个线程(任务)完成后,进行汇总合并的场景。

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怎么使用多线程解决主线程提前结束问题”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: java怎么使用多线程解决主线程提前结束问题

本文链接: https://www.lsjlt.com/news/351262.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • java怎么使用多线程解决主线程提前结束问题
    这篇文章主要介绍“java怎么使用多线程解决主线程提前结束问题”,在日常操作中,相信很多人在java怎么使用多线程解决主线程提前结束问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java怎么使用多线程解决...
    99+
    2023-07-05
  • java之使用多线程代替for循环(解决主线程提前结束问题)
    目录CountDownLatch常用方法使用案例应用场景场景1:模拟并发场景2:多个线程完成后,进行汇总合并接下来进入正题总结在使用之前先介绍一个并发需要用到的方法: CountDo...
    99+
    2023-03-10
    java使用多线程 java for循环 java主线程
  • Java多线程之线程安全问题怎么解决
    本篇内容主要讲解“Java多线程之线程安全问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java多线程之线程安全问题怎么解决”吧!1.线程安全概述1.1什么是线程安全问题首先我们需要...
    99+
    2023-06-30
  • Java多线程死锁问题怎么解决
    解决Java多线程死锁问题的常用方法有以下几种:1. 避免使用多个锁:尽量减少使用多个锁来降低出现死锁的概率。2. 按照固定的顺序获...
    99+
    2023-09-22
    Java
  • Java多线程 - 线程安全和线程同步解决线程安全问题
    文章目录 线程安全问题线程同步方式一: 同步代码块方式二: 同步方法方式三: Lock锁 线程安全问题 线程安全问题指的是: 多个线程同时操作同一个共享资源的时候可能会出现业务安全问题,称为线程安全问题。 举例:...
    99+
    2023-08-20
    java 安全 jvm
  • Java使用线程同步解决线程安全问题详解
    第一种方法:同步代码块: 作用:把出现线程安全的核心代码上锁 原理:每次只能一个线程进入,执行完毕后自行解锁,其他线程才能进来执行 锁对象要求:理论上,锁对象只要对于当前同时执行的线...
    99+
    2024-04-02
  • Java多线程之线程安全问题详解
    目录1. 什么是线程安全和线程不安全?2. 自增运算为什么不是线程安全的?3. 临界区资源和竞态条件总结:面试题: 什么是线程安全和线程不安全?自增运算是不是线程安全的?如何保证多线...
    99+
    2024-04-02
  • 如何解决Java多线程死锁问题
    死锁问题 死锁定义 多线程编程中,因为抢占资源造成了线程无限等待的情况,此情况称为死锁。 死锁举例 注意:线程和锁的关系是:一个线程可以拥有多把锁,一个锁只能被一个线程拥有。 当两个...
    99+
    2024-04-02
  • java多线程并发问题如何解决
    在Java中,可以使用以下方法来解决多线程并发问题:1. 使用synchronized关键字:可以通过在方法或代码块前加上synch...
    99+
    2023-09-27
    java
  • MFC多线程传参问题怎么解决
    本篇内容主要讲解“MFC多线程传参问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MFC多线程传参问题怎么解决”吧!在一个程序中,这些独立运行的程序片断叫作“线程”(Thread),利...
    99+
    2023-06-17
  • QT中TerminateThread不能结束线程怎么解决
    在QT中,TerminateThread函数不能安全地结束线程,因为它会导致线程突然终止,可能会导致资源泄露或者死锁的情况发生。相反...
    99+
    2024-02-29
    QT
  • Java子线程任务异常和主线程事务回滚问题怎么解决
    这篇文章主要介绍了Java子线程任务异常和主线程事务回滚问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java子线程任务异常和主线程事务回滚问题怎么解决文章都会有所收获,下面我们一起来看看吧。一、提...
    99+
    2023-06-30
  • java treemap线程安全问题怎么解决
    要解决Java TreeMap的线程安全问题,有以下几种方法:1. 使用Collections.synchronizedMap()方...
    99+
    2023-10-20
    java
  • Java多线程下解决数据安全问题
    目录同步代码块同步方法lock锁同步代码块 基本语句 synchronized (任意对象) { 操作共享代码 } 代码示例 public class SellTicket ...
    99+
    2024-04-02
  • java for循环内执行多线程问题怎么解决
    这篇文章主要介绍了java for循环内执行多线程问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇java for循环内执行多线程问题怎么解决文章都会有所收获,下面我们一起来看看吧...
    99+
    2023-07-05
  • springboot多线程高并发问题怎么解决
    要解决Spring Boot多线程高并发问题,你可以考虑以下几个方面:1. 线程池配置:合理配置线程池的大小、队列容量等参数,以满足...
    99+
    2023-08-24
    springboot
  • Java多线程解决龟兔赛跑问题详解
    目录多线程4(龟兔赛跑-休眠线程)1.题目2.解题思路3.代码详解多线程4(龟兔赛跑-休眠线程) 1.题目 在龟兔赛跑中,领先的兔子因为通宵写博客,中途太累睡着了,跑输了乌龟。这个故...
    99+
    2024-04-02
  • python多线程效率低问题怎么解决
    Python中的多线程效率低的问题主要是由于Python的全局解释器锁(GIL)导致的。GIL是Python解释器中的一个机制,它确...
    99+
    2023-09-04
    python
  • Python互斥锁怎么解决多线程问题
    这篇文章给大家分享的是有关Python互斥锁怎么解决多线程问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。python主要应用领域有哪些1、云计算,典型应用OpenStack。2、WEB前端开发,众多大型网站均...
    99+
    2023-06-14
  • java怎么使用线程池启动多线程
    在 Java 中,可以使用线程池来启动多线程。以下是使用线程池启动多线程的示例代码:首先,需要导入 `java.util.concu...
    99+
    2023-09-15
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作