V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
nxforce
V2EX  ›  Java

JDK11 的新 HTTP client API 搭配线程池把我的电脑搞挂了

  •  
  •   nxforce · Sep 10, 2021 · 4451 views
    This topic created in 1689 days ago, the information mentioned may be changed or developed.

    1.创建线程池

    final ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
    
    

    2.创建 http 请求

    var builder = HttpRequest.newBuilder()
                    .uri(URI.create(uri));
    HttpRequest request =
                        builder.POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8)).build();
    //发送请求
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    

    3.创建任务,丢给线程池

    List<CompletableFuture<?>> futures = new ArrayList<>();
            for (User user : Users) {
                CompletableFuture<?> future = CompletableFuture.runAsync(() -> {
                      用上面的 http 请求
                }, threadPoolExecutor);
    
                futures.add(future);
            }
    
            //等待所有任务完成
            final int taskCount = futures.size();
            CompletableFuture<?> allFuture = CompletableFuture.allOf((futures.toArray(new CompletableFuture[taskCount])));
            allFuture.join();
    
            //关闭线程池
            threadPoolExecutor.shutdown();
    

    4.User 数是 2000 多,也就是任务数才 2000 多,就把我系统资源爆了,提示不能再继续创建 thread 了,我的 macOS 直接黑屏重启

    我寻思我创建的线程池才 5 个,不至于让我的系统挂了吧?那元凶可能是 http 新的 client api 自己再私自创建大量线程,直到耗尽系统的线程资源数?有无大佬指教一下怎么优化?我就想我请求只限制在 5 个线程以内

    Supplement 1  ·  Sep 10, 2021

    谢谢大家,我传入一个单线程的池子给httpclient的builder就没问题了。

    15 replies    2021-09-11 10:45:50 +08:00
    buster
        1
    buster  
       Sep 10, 2021
    HttpRequest 看下有没有资源需要释放,close 之类的?
    nutting
        2
    nutting  
       Sep 10, 2021
    这么多 http 请求很多了
    nxforce
        3
    nxforce  
    OP
       Sep 10, 2021
    @nutting 线程池才给 5 条线程做请求哦。
    yazinnnn
        4
    yazinnnn  
       Sep 10, 2021
    val client: HttpClient = HttpClient.newBuilder().executor(threadPoolExecutor).build()

    用这个试试?

    client.sendAsync()

    发送请求用 HttpClient 的异步 api
    securityCoding
        5
    securityCoding  
       Sep 10, 2021
    你给的信息太少,不知道你的代码具体结构怎么组织的,提供几个思路
    1. client 可以复用(an HttpClient is immutable, and can be used to send multiple requests.)
    2. 线程池复用,为什么要在方法内关闭呢?
    3. allFuture.join()是否应该改成 allFuture.get()
    123zouwen
        6
    123zouwen  
       Sep 10, 2021   ❤️ 1
    用之前至少先翻看一下 api 和源码吧

    构建 HttpClient 的时候可以传入 Executor,查看源码没有传入会有一个默认的 Executors.newCachedThreadPool(new DefaultThreadFactory(id)

    而且 jdk11 新的 HTTP client API 本身就可以发异步请求返回 CompletableFuture
    一个 java11 httpclient 例子你简单看一下,
    https://github.com/app2smile/java11-HttpClient-Util/blob/main/JdkHttpClientUtil.java
    ForkNMB
        7
    ForkNMB  
       Sep 10, 2021
    首先,不建议使用 Executors.newFixedThreadPool 创建线程池,阻塞队列大小是没有大小限制的,如果队列堆积数据太多会造成资源消耗,手动指定一下线程池参数吧。
    securityCoding
        8
    securityCoding  
       Sep 10, 2021
    @123zouwen 看了一下源码,你是对的
    wellsc
        9
    wellsc  
       Sep 10, 2021
    hhh
    ikas
        10
    ikas  
       Sep 10, 2021
    1.你这个 httpclient 根本就没有用你配置的 threadPoolExecutor ....
    你只是自己写了一个异步
    ,CompletableFuture.runAsync(() -> {
    用上面的 http 请求
    }, threadPoolExecutor);
    ,你应该直接用 httpclient 内置的 async 方法,同时给其配置线程池

    2.你这么多请求全部等待...内存肯定耗尽了..所以 httpclient 内部也没有办法创建进程了..
    3.内存崩了系统挂了..那么应该是系统问题....
    BBCCBB
        11
    BBCCBB  
       Sep 10, 2021
    所以看起来是 sendAsync 的时候用的默认的 CachedThreadPool() 导致的创建了太多线程?

    这个线程看起来是异步执行完后的回调线程.

    是 completeAsync(() -> null, executor) 导致的?
    DonaldY
        12
    DonaldY  
       Sep 10, 2021
    httpClient 线程池 没设置
    dqzcwxb
        13
    dqzcwxb  
       Sep 10, 2021
    啥也不知道就让别人改线程池参数是最搞笑的,说一句正确的废话
    dqzcwxb
        14
    dqzcwxb  
       Sep 10, 2021

    HttpClientImpl.java:277
    贴上源码地址方便后来人
    guyeu
        15
    guyeu  
       Sep 11, 2021
    题外话,旧版本的 HttpClient 确实有连接泄露的 bug,想在生产环境中用最好升级

    https://bugs.openjdk.java.net/browse/JDK-8241810
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3037 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 123ms · UTC 00:03 · PVG 08:03 · LAX 17:03 · JFK 20:03
    ♥ Do have faith in what you're doing.