CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽

这篇具有很好参考价值的文章主要介绍了CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

错误描述:

        我设置了CountDownLatch对线程的协作做出了一些限制,但是我发现运行一段时间以后便发现定时任务不运行了。

具体代码:

public void sendToCertainWeb() throws IOException, InterruptedException {
        List<String> urlList = scheduleplanMapper.getRandomUrlList();
        Thread.sleep(6000);
        CountDownLatch countDownLatch = new CountDownLatch(20);
        for (String s : urlList) {
            transportThreadPool.execute(()->{
                try {
                    URL url = new URL(s);
                    // 打开连接
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                    // 设置请求方法为GET
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(100000);
                    connection.setReadTimeout(100000);

                    // 添加自定义的请求头信息
                    String agent = scheduleplanMapper.getRandomAgent();
                    connection.addRequestProperty("User-Agent", agent);
                    connection.addRequestProperty("Accept-Language", "en-US,en;q=0.9");

                    // 获取服务器返回的状态码
                    int responseCode = connection.getResponseCode();

                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        // 读取服务器返回的数据
                        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

                        String line;
                        StringBuilder response = new StringBuilder();

                        while ((line = reader.readLine()) != null) {
                            response.append(line);
                        }
                        reader.close();
                        log.info("Right Code: " + responseCode);
                    } else {
                        log.error("Error Code: " + responseCode);
                    }

                    // 关闭连接
                    connection.disconnect();
                    countDownLatch.countDown();
                }catch (Exception e){
                    log.error(JSON.toJSONString(e));

                }

            });
        }
        countDownLatch.await();
    }

报错以后定时任务不运行了 

CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽,windows

CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽,windows

错误排查:

 打印线程日志发现定时任务的线程在第86行代码停着不动了。

CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽,windows

正常的线程日志应该是这样的。

CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽,windows

查看第86行代码,发现这里并没有唤醒主线程 ,导致线程一直处于运行状态,无法继续下一个任务。

CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽,windows

        错误的原因是countDownLatch.countDown()并没有放在finally块里因此发生了错误并不会走这块代码,导致线程没有countDown

CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽,windows

错误修改:

把countDownLatch.countDown();放在finally代码块里保证一定会进行countDown这个动作

正确代码:

    public void sendToCertainWeb() throws IOException, InterruptedException {
        List<String> urlList = scheduleplanMapper.getRandomUrlList();
        Thread.sleep(6000);
        CountDownLatch countDownLatch = new CountDownLatch(20);
        for (String s : urlList) {
            transportThreadPool.execute(()->{
                try {
                    URL url = new URL(s);
                    // 打开连接
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                    // 设置请求方法为GET
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(100000);
                    connection.setReadTimeout(100000);

                    // 添加自定义的请求头信息
                    String agent = scheduleplanMapper.getRandomAgent();
                    connection.addRequestProperty("User-Agent", agent);
                    connection.addRequestProperty("Accept-Language", "en-US,en;q=0.9");

                    // 获取服务器返回的状态码
                    int responseCode = connection.getResponseCode();

                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        // 读取服务器返回的数据
                        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

                        String line;
                        StringBuilder response = new StringBuilder();

                        while ((line = reader.readLine()) != null) {
                            response.append(line);
                        }
                        reader.close();
                        log.info("Right Code: " + responseCode);
                    } else {
                        log.error("Error Code: " + responseCode);
                    }

                    // 关闭连接
                    connection.disconnect();

                }catch (Exception e){
                    log.error(JSON.toJSONString(e));
                }finally {
                    countDownLatch.countDown();
                }

            });
        }
        countDownLatch.await();
    }

错误总结:

         我们一般认为线程处于blocked状态的时候线程才是处于阻塞状态,但是这个状态只是对于计算机来说的。对于我们来说,只要业务不执行了,线程就是处于阻塞状态的,因此任何状态下的线程对于业务来说都是阻塞的。 我这个项目是爬虫项目,会去爬取别人网站的数据,有些网站识别爬虫之后不仅会拒绝你访问,还会通过一直不给响应使得你的服务器线程占满,进而导致你的爬虫服务器崩溃。

参考文章: 

未设置超时时间导致线程池资源耗尽,排查过程-CSDN博客文章来源地址https://www.toymoban.com/news/detail-856963.html

到了这里,关于CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WPF 已知问题 传入错误数据给到 WriteableBitmap 可能导致渲染线程锁住

    本文记录一个 WPF 已知问题,此问题已经被我修复。传入错误的数据给到 WriteableBitmap 对象,比如调用 WritePixels 时传入错误的 stride 数值,将可能导致渲染线程进入无限自旋锁 应用程序停止渲染,或者是界面未响应。表现是在 渲染 线程卡住,从任务管理器看可以看到有一个

    2024年02月09日
    浏览(28)
  • 记一次swoole连接数太多导致的错误

    原先就有点担心这个项目正式上线会出现各种问题,所以刚上线就赶紧查看日志 果然,频繁出现错误: WARNING Server::accept_connection(): accept() failed, Error: Too many open files[24] 这个错误通常是由于操作系统限制了进程能够打开的文件句柄数量,导致当前进程无法打开更多的文件,从

    2024年02月02日
    浏览(39)
  • FileZilla仅开放21端口导致连接超时错误:读取目录列表失败

    条件:         部署FileZilla Server后,在防火墙内打开21端口入站。         另一台机器使用FileZilla连接服务器,卡在如下:                 状态:    连接建立,等待欢迎消息...                 状态:    初始化 TLS 中...                 状态:    

    2024年02月05日
    浏览(29)
  • 巧用CountDownLatch实现多线程并行工作

    【前言】       CountDownLatch 是JDK提供的一个同步工具,它可以让一个或多个线程挂起等待,一直等到其他线程执行完成才会继续执行。常用方法有 countDown 方法和 await 方法, CountDownLatch 在初始化时,需要指定一个整数n作为计数器。当调用 countDown 方法时,计数器会被减1;

    2024年02月13日
    浏览(27)
  • 【Java基础】线程同步类 CountDownLatch

    ​ 关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 正好今天项目中用到了CountDownLatch,那我们正好总结一下,通过本文你可以学到什么是CountDownLatch及其原理,

    2024年02月12日
    浏览(38)
  • 使用java完成WebSocket自动主动断开连接功能

    一个页面实时刷新的功能,页面上的数据状态可能会随着操作实时改变,所以每个用户在使用的时候都希望能看到数据的最新状态。 我想到了两种解决方法:1.轮循,2.WebSocket 我们这里采用的是WebSocket来解决问题 WebSocket在建立连接后,如果不是人为操作的话,他不会主动地进

    2024年02月07日
    浏览(41)
  • mac使用VsCode远程连接服务器总是自动断开并要求输入密码的解决办法

    在mac中使用vscode远程连接服务器,时常会出现自动断开并要求重新输入服务器密码的问题,接下来让我们来解决它: 1、首先,在本地创建公钥: 这条命令执行之后,出现提示直接回车即可;直到遇到Overwrite (y/n)?  输入y,之后继续回车,如下图:  2、将本地mac密匙的 id_rs

    2024年02月10日
    浏览(48)
  • 原子类-入门介绍和分类说明、基本类型原子类、Join和CountDownLatch都可以让一个线程等待子线程完成

    Atomic翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学 反应中是不可分割的。在我们这里Atomic是指一个操作是不可中断的。即使是在多个线程一起执 行的时候,一个操作一旦开始,就不会被其他线程干扰。 基本类型原子类 AtomicInteger :

    2024年01月20日
    浏览(31)
  • 线程池使用不规范导致线程数大以及@Async的规范使用

    文章详细内容来自:线程数突增!领导:谁再这么写就滚蛋! 下面是看完后文章的,一个总结 线程池的使用不规范,导致程序中线程数不下降,线程数量大。 临时变量的接口,通过下面简单的线程池执行, 线程不被GC回收,主要是线程池的gc root还是有可达路径的。这里讲个

    2024年02月10日
    浏览(28)
  • 【调试记录】QT中使用多线程导致的死锁

    原因在于第18行采用阻塞队列的连接方式。 子线程在第17行获取到锁,主线程刚好运行到24行准备获取锁。此时子线程执行第18行,阻塞调用等待主线程执行 qDebug() \\\"invokeMethod:\\\" ++count_; 完成。 子线程已经获取到锁,主线程等待获取锁,子线程又等待主线程事件循环执行函数,由

    2023年04月16日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包