URLConnection 类整个请求到响应一直占用cpu吗?

零度
  • 3
新手上路,请多包涵
当前代码无法获取到阻塞状态 只有RUNNABLE、TERMINATED
如何获取等待链接响应和资源响应的空档期? 我想在等待资源时去再开同样的线程直到一直有资源不断响应方才中止
测试类
package runing;

import java.util.Formatter;
import java.util.logging.Logger;

public class Test {

    public static void main(String[] args) throws InterruptedException {
        //ExecutorService exec = Executors.newSingleThreadExecutor();
        final Logger log = Logger.getLogger(String.valueOf(String.class));
        MaThread maThread = new MaThread(1);
        maThread.start();
        Thread.State state = maThread.getState();
        do {
            state = maThread.getState();
            if (state != Thread.State.RUNNABLE && state != Thread.State.TERMINATED) {
                log.info(new Formatter().format("状态:%s ;", state).toString());
            }
        } while (state != Thread.State.TERMINATED);
//        IntStream.range(0, 1).mapToObj(MaThread::new).forEach(thread1 -> thread1.start());
    }
}
线程类:用独立线程获取网络请求
package runing;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Logger;
import java.util.stream.Collectors;

public class MaThread extends Thread {

    final Logger log = Logger.getLogger(String.valueOf(String.class));

    public static int index = 0;

    MaThread(int i) {
    }

    @Override
    public void run() {
        try {
            URL realUrl = new URL("http://www.baidu.com");
            try {
                URLConnection connection = realUrl.openConnection();
                connection.connect();
                InputStream inputStream = connection.getInputStream();
                String res = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining(System.lineSeparator()));
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (MalformedURLException e) {
            log.info(e.getMessage());
        }
    }
}

是这样的流程

回复
阅读 718
2 个回答
✓ 已被采纳

大概明白问题的意思,是想着在 IO 阻塞期间开个新线程,同时获取到阻塞结束的事件吧。可以这么做,将你这段 URLConn 的代码,用一个 Callable 子线程执行,丢到线程池里跑,然后在另一个线程中调用这个 Future.get(),这不就能拿到请求完成的事件了?

ExecutorService executorService = Executors.newSingleThreadExecutor();
        Future<String> future = executorService.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                try {
                    URL realUrl = new URL("http://www.baidu.com");
                    try {
                        URLConnection connection = realUrl.openConnection();
                        connection.connect();
                        InputStream inputStream = connection.getInputStream();
                        String res = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining(System.lineSeparator()));
                        inputStream.close();
                        return res;
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                catch (MalformedURLException e) {
                    log.info(e.getMessage());
                }
            }
        });
        //submit之后,就可以干你想干的事,比如”等待资源时去再开同样的线程直到一直有资源不断响应方才中止“
        
        //获取返回
        String res = future.get();

我的理解是,你有个线程Thread-1,这个线程发送http请求后,因为网络原因,Thread-1会有一段阻塞期。你想要在线程阻塞期间开一个新线程(这里我没有看明白,是开一个,还是不断开新线程),然后你需要在Thread-1阻塞结束后,有一个通知机制,去通知main线程不在阻塞了吗?

而且关于你那个检查线程(暂且叫做A)运行状态的例子本身就不对,因为cpu的分片机制,和你自己cpu的物理核心数,都会导致A.getState返回的结果。他可能因为时间片到了,才变为等待状态,也可能是还在因为网络问题,处于等待状态。如果你cpu是单核的,那么当maThread.getState()被调用时,A线程必然不可能是运行状态,也就是直到A线程结束。你获取到的A的状态可能一直是TIMED_WAITING。

你知道吗?

宣传栏