中断正在Java中进行HTTP调用的线程

Rag*_*ani 5 java multithreading http threadpoolexecutor

我正在编写一个Java程序,以在另一个线程中对服务器进行HTTP调用。我在线程池执行程序中的单独Callable任务中执行以下代码。

public static class MyRunnable implements Callable<Boolean>{

    @Override
    public Boolean call() {
        HttpURLConnection conn = null;
        try {
            URL url = new URL("http://www.myserver.com");
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setRequestMethod("GET");
            int response = conn.getResponseCode();
                            return response == 200;
        }
        catch (IOException e) {
            e.printStackTrace();
                            return false;
        } catch (Exception e) {
            e.printStackTrace();
                            return false;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

由于某些原因,服务器不响应或服务器响应非常慢。由于该服务器的行为,连接超时和读取超时都不会发生。

因此,我想监视此任务(在线程池执行程序中运行),并在一段时间后中断线程,并确保从池中删除此任务,以便线程池不包含此任务并释放此任务占用的所有资源。线。

我尝试Future了如下的java

 ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 5, 5, TimeUnit.SECONDS, new      ArrayBlockingQueue<Runnable>(10));
 Future<Boolean> f = tpe.submit(new MyRunnable());
  try {
        Boolean success = f.get(5000, TimeUnit.MILLISECONDS);
    } catch (Exception e) {
        e.printStackTrace();
    }
Run Code Online (Sandbox Code Playgroud)

有了这段代码,如果正在处理任务的线程没有响应,我将在5000毫秒后TimeoutExceptionf.get调用中得到MyRunnable。但是我可以看到,如果任务停留在,它将继续在线程池执行程序中运行HttpURLConnection.getResponseCode()

当我尝试时f.cancel(true),当任务停留在HttpURLConnection.getResponseCode()方法调用时,它不会中断线程。我知道线程只有在下一个可用机会中对其进行测试时才会被中断。因此,我想future.cancel在这种情况下没有帮助。

那么,如何从此调用中退出(通过与线程池执行程序进行交互),并确保从池中删除了任务,并且相应的线程可以自由地处理不同的任务?

感谢您的提前答复。

谢谢,

拉古

小智 0

我认为您可以与另一个线程共享连接,该线程会在超时后调用disconnect()。所以,它应该是这样的:

static class ConnectionStopper implements Runnable {

    private final HttpURLConnection conn;

    ConnectionStopper(HttpURLConnection conn) {
        if (conn == null) {
            throw new NullPointerException();
        }
        this.conn = conn;
    }

    @Override
    public void run() {
        conn.disconnect();
    }
}

...

ScheduledExecutorService service = Executors.newScheduledThreadPool(THREAD_POOL_SIZE);
...
// Submit your MyRunnable, then schedule a ConnectionStopper
service.schedule(new ConnectionStopper(conn), 5, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)