How to cancel a thread making a http request from another thread How to cancel a thread making a http request from another thread multithreading multithreading

How to cancel a thread making a http request from another thread


The thread that made the request is blocked while waiting the server to respond. If you take a thread dump and see, it will be in some read() method, but not on a Thread.sleep. So calling interrupt() will not have an effect (unless it's an InterruptibleChannel).Do you have access to the socket or the output stream on which the POST request was made? If so, you can close that, which will bring out of the read wait with an exception.Do you have a code sample that you can put up?


Helloo everyone, finally got this closing socket idea implemented and working. below is the snippet i tried.

my Requesting thread

package com.pkg.myhttptest;import org.apache.http.client.methods.HttpPost;public class RequestThread implements Runnable{    Message msg = null;    Util util = null;    public RequestThread(Message msg, Util util) {        this.msg = msg;        this.util = util;    }    public void run() {        System.out.println("its request thread");        util.print(msg);    }}

Cancelling Thread

public class CancelThread implements Runnable {    Message msg = null;    Util util = null;    public CancelThread(Message msg, Util util) {        this.msg = msg;        this.util = util;    }    public void run() {        System.out.println("its cancel thread");        int i=0;        while(i<5){            System.out.println("looping" + i);            i++;        }        System.out.println(msg.getHttpost() + "In cancelled");        Header[] hdr = msg.getHttpost().getAllHeaders();        System.out.println(hdr.length + "length");        msg.getHttpost().abort();        System.out.println(msg.getHttpost().isAborted());    }}

Shared Object

public class Message {    HttpPost httpost;    public HttpPost getHttpost() {        return httpost;    }    public void setHttpost(HttpPost httpost) {        this.httpost = httpost;    }}

Util Class

public class Util {    private final String USER_AGENT = "Mozilla/5.0";    public void print(Message msg) {        String url = "https://selfsolve.apple.com/wcResults.do";        HttpPost post = new HttpPost(url);        HttpClient client = HttpClientBuilder.create().build();         post.setHeader("User-Agent", USER_AGENT);        List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();        urlParameters.add(new BasicNameValuePair("sn", "C02G8416DRJM"));        urlParameters.add(new BasicNameValuePair("cn", ""));        urlParameters.add(new BasicNameValuePair("locale", ""));        urlParameters.add(new BasicNameValuePair("caller", ""));        urlParameters.add(new BasicNameValuePair("num", "12345"));        try {            post.setEntity(new UrlEncodedFormEntity(urlParameters));            msg.setHttpost(post);            HttpResponse response = client.execute(post);            System.out.println("Response Code : " + response.getStatusLine().getStatusCode());            BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));            StringBuffer result = new StringBuffer();            String line = "";            while ((line = rd.readLine()) != null) {                result.append(line);            }        } catch (UnsupportedEncodingException e) {        } catch (IOException e) {           e.printStackTrace()        }    }

Main Class

public class App {    public static void main( String[] args )    {        Message msg = new Message();        Util util = new Util();        Thread reqThread = new Thread(new RequestThread(msg, util));        Thread cancelThread = new Thread(new CancelThread(msg, util));        System.out.println("Starting Threads");        reqThread.start();        try {            reqThread.sleep(2000);            cancelThread.start();            cancelThread.join();            System.out.println("closing..");        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

Its little uncleaned code I agree, but it works. It results in below exception and kills the thread.

java.net.SocketException: Socket is closed    at java.net.Socket.getInputStream(Socket.java:876)    at sun.security.ssl.SSLSocketImpl.doneConnect(SSLSocketImpl.java:644)    at sun.security.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:549)

Thanks everyone who has put their efforts in helping me.


I was trying to solve the same thing. I wrote an HTTP Request Runnable that took 20 seconds to timeout and executed on one thread (1st Thread). I wrote a Timeout Runnable on a separate thread (2nd Thread) that was supposed to interrupt/stop the 1st Thread after 10 seconds. For every second in the Main Thread (3 threads total), I printed the state of the threads and found the 1st thread kept running.

import java.util.Collections;import java.util.LinkedHashMap;import java.util.Map;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.util.EntityUtils;public class A_Test_Thread_Interrupt {    public static final String URL_THAT_CAUSES_CONNECTION_TIMED_OUT_AFTER_20_SECONDS = "https://..."; // Need to provide this for your system.  Must timeout after 20 seconds//  java.net.ConnectException: Connection timed out: connect//  at java.net.DualStackPlainSocketImpl.connect0(Native Method)//  at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)//  at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)//  at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)//  at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)//  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)//  at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)//  at java.net.Socket.connect(Socket.java:589)//  at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:542)//  at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:414)//  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)//  at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:326)//  at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610)//  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445)//  at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835)//  at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)//  at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)//  at A_Test_Thread_Interrupt$HttpRequestRunnable.run(A_Test_Thread_Interrupt.java:35)//  at java.lang.Thread.run(Thread.java:748)    public static void main(String[] args) {        System.out.println("main Start");        long startTime = System.currentTimeMillis();        SharedData sd = new SharedData();        System.out.println("Starting HTTPS Request Thread");        HttpRequestRunnable httpRequestRunnable = new HttpRequestRunnable(sd);        Thread workerThread = new Thread(httpRequestRunnable);        workerThread.start();//      workerThread.stop();        System.out.println("Starting Timeout Thread");        TimeoutRunnable timeoutRunnable = new TimeoutRunnable(workerThread, httpRequestRunnable, sd);        Thread timeoutThread = new Thread(timeoutRunnable);        timeoutThread.start();        for(int i=0; i<30; i++) {            System.out.println("workerThread.getState():"+workerThread.getState()+" timeoutThread.getState():"+timeoutThread.getState());            try { // Sleep for 1 second                Thread.sleep(1*1000);            } catch (Exception ex) {                ex.printStackTrace();            }        }        long endTime = System.currentTimeMillis();        System.out.println("main End timeInSeconds:"+(endTime-startTime)/1000);    }    public static class HttpRequestRunnable implements Runnable {        SharedData sharedData;        public HttpRequestRunnable (SharedData sharedData) {            this.sharedData = sharedData;            sharedData.setIsFinished(this, false);        }        public void run() {            System.out.println("Running HttpRequestRunnable Runner Start");            long startTime = System.currentTimeMillis();            try {                HttpGet httpGet = new HttpGet(URL_THAT_CAUSES_CONNECTION_TIMED_OUT_AFTER_20_SECONDS);                CloseableHttpResponse response = new DefaultHttpClient().execute(httpGet);                String responseString = EntityUtils.toString(response.getEntity());                System.out.println("responseString:"+responseString);                sharedData.setIsFinished(this, true);            } catch (Exception ex) {                ex.printStackTrace();            }            long endTime = System.currentTimeMillis();            System.out.println("Running HttpRequestRunnable Runner End timeInSeconds:"+(endTime-startTime)/1000);        }    }    public static class SharedData {        Map<Runnable, Boolean> isFinishedMap = Collections.synchronizedMap(new LinkedHashMap<Runnable, Boolean>());        public void setIsFinished(Runnable runnable, Boolean value) {            synchronized(isFinishedMap) {                isFinishedMap.put(runnable, value);            }        }        public Boolean getIsFinished(Runnable runnable) {            synchronized(isFinishedMap) {                return isFinishedMap.get(runnable);            }        }    }    public static class TimeoutRunnable implements Runnable {        Thread workerThreadToKillIfItTakesTooLong;        Runnable runnable;        SharedData sharedData;        public TimeoutRunnable(Thread workerThreadToKillIfItTakesTooLong, Runnable runnable, SharedData sharedData) {            this.workerThreadToKillIfItTakesTooLong = workerThreadToKillIfItTakesTooLong;            this.runnable = runnable;            this.sharedData = sharedData;        }        public void run() {            System.out.println("Running TimeoutRunnable Runnable Start");            long startTime = System.currentTimeMillis();            int secondsToSleep = 1;            int iterationsPerNote = 2;            int iterations = 10;            for(int i=0; i<iterations; i++) { // Sleep for at most 10 seconds                boolean workerRunnableIsFinished = sharedData.getIsFinished(runnable);                if(workerRunnableIsFinished) {                    return;                } else {                    if(i % iterationsPerNote == 0) { // Print a message every 2 iterations                        System.out.println("TimeoutRunnable waiting for workerRunnable...");                    }                }                try { // Sleep for 1 second                    Thread.sleep(secondsToSleep*1000);                } catch (Exception ex) {                    ex.printStackTrace();                }            }            // 5 minutes have passed, kill thread            System.out.println("Killing worker thread for taking too long");            workerThreadToKillIfItTakesTooLong.stop();            sharedData.setIsFinished(runnable, true);            long endTime = System.currentTimeMillis();            System.out.println("Running TimeoutRunnable Runnable End timeInSeconds:"+(endTime-startTime)/1000);        }    }}

Here was the output

main: main Startmain: Starting HTTPS Request Threadmain: Starting Timeout Thread1st_: Running HttpRequestRunnable Runner Startmain: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE2nd_: Running TimeoutRunnable Runnable Start2nd_: TimeoutRunnable waiting for workerRunnable...main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE2nd_: TimeoutRunnable waiting for workerRunnable...main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLEmain: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE2nd_: TimeoutRunnable waiting for workerRunnable...main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLEmain: workerThread.getState():RUNNABLE timeoutThread.getState():TIMED_WAITING2nd_: TimeoutRunnable waiting for workerRunnable...main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLEmain: workerThread.getState():RUNNABLE timeoutThread.getState():TIMED_WAITING2nd_: TimeoutRunnable waiting for workerRunnable...main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLEmain: workerThread.getState():RUNNABLE timeoutThread.getState():TIMED_WAITING2nd_: Killing worker thread for taking too longmain: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE2nd_: Running TimeoutRunnable Runnable End timeInSeconds:10main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATEDmain: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATEDmain: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATEDmain: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATEDmain: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATEDmain: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATEDmain: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATEDmain: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATEDmain: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATEDmain: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATEDmain: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: main End timeInSeconds:30

I use a SharedData class to hold information needed by both threads. By adding the extra information needed to terminate the thread (ie the HttpGet), I can have the monitoring thread do whatever is necessary to actually terminate the thread (ie call httpGet.abort). This is the modified code (modified lines end with // MOD)

import java.util.Collections;import java.util.LinkedHashMap;import java.util.Map;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.util.EntityUtils;public class A_Test_Thread_Interrupt {    public static final String      public static final String URL_THAT_CAUSES_CONNECTION_TIMED_OUT_AFTER_20_SECONDS = "https://..."; // Need to provide this for your system.  Must timeout after 20 seconds//  java.net.ConnectException: Connection timed out: connect//  at java.net.DualStackPlainSocketImpl.connect0(Native Method)//  at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)//  at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)//  at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)//  at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)//  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)//  at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)//  at java.net.Socket.connect(Socket.java:589)//  at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:542)//  at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:414)//  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)//  at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:326)//  at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610)//  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445)//  at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835)//  at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)//  at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)//  at A_Test_Thread_Interrupt$HttpRequestRunnable.run(A_Test_Thread_Interrupt.java:35)//  at java.lang.Thread.run(Thread.java:748)    public static void main(String[] args) {        System.out.println("main Start");        long startTime = System.currentTimeMillis();        SharedData sd = new SharedData();        System.out.println("Starting HTTPS Request Thread");        HttpRequestRunnable httpRequestRunnable = new HttpRequestRunnable(sd);        Thread workerThread = new Thread(httpRequestRunnable);        workerThread.start();//      workerThread.stop();        System.out.println("Starting Timeout Thread");        TimeoutRunnable timeoutRunnable = new TimeoutRunnable(workerThread, httpRequestRunnable, sd);        Thread timeoutThread = new Thread(timeoutRunnable);        timeoutThread.start();        for(int i=0; i<30; i++) {            System.out.println("workerThread.getState():"+workerThread.getState()+" timeoutThread.getState():"+timeoutThread.getState());            try { // Sleep for 1 second                Thread.sleep(1*1000);            } catch (Exception ex) {                ex.printStackTrace();            }        }        long endTime = System.currentTimeMillis();        System.out.println("main End timeInSeconds:"+(endTime-startTime)/1000);    }    public static class HttpRequestRunnable implements Runnable {        SharedData sharedData;        public HttpRequestRunnable (SharedData sharedData) {            this.sharedData = sharedData;            sharedData.setIsFinished(this, false);        }        public void run() {            System.out.println("Running HttpRequestRunnable Runner Start");            long startTime = System.currentTimeMillis();            try {                HttpGet httpGet = new HttpGet(URL_THAT_CAUSES_CONNECTION_TIMED_OUT_AFTER_20_SECONDS);                sharedData.setHttpGet(this, httpGet); // MOD                CloseableHttpResponse response = new DefaultHttpClient().execute(httpGet);                String responseString = EntityUtils.toString(response.getEntity());                System.out.println("responseString:"+responseString);                sharedData.setIsFinished(this, true);            } catch (Exception ex) {                ex.printStackTrace();            }            long endTime = System.currentTimeMillis();            System.out.println("Running HttpRequestRunnable Runner End timeInSeconds:"+(endTime-startTime)/1000);        }    }    public static class SharedData {        Map<Runnable, Boolean> isFinishedMap = Collections.synchronizedMap(new LinkedHashMap<Runnable, Boolean>());        Map<Runnable, HttpGet> httpGetMap = Collections.synchronizedMap(new LinkedHashMap<Runnable, HttpGet>()); // MOD        public void setIsFinished(Runnable runnable, Boolean value) {            synchronized(isFinishedMap) {                isFinishedMap.put(runnable, value);            }        }        public Boolean getIsFinished(Runnable runnable) {            synchronized(isFinishedMap) {                return isFinishedMap.get(runnable);            }        }        public void setHttpGet(Runnable runnable, HttpGet httpGet) { // MOD            synchronized(httpGetMap) { // MOD                httpGetMap.put(runnable, httpGet); // MOD            } // MOD        } // MOD        public HttpGet getHttpGet(Runnable runnable) { // MOD            synchronized(httpGetMap) { // MOD                return httpGetMap.get(runnable); // MOD            } // MOD        } // MOD    }    public static class TimeoutRunnable implements Runnable {        Thread workerThreadToKillIfItTakesTooLong;        Runnable runnable;        SharedData sharedData;        public TimeoutRunnable(Thread workerThreadToKillIfItTakesTooLong, Runnable runnable, SharedData sharedData) {            this.workerThreadToKillIfItTakesTooLong = workerThreadToKillIfItTakesTooLong;            this.runnable = runnable;            this.sharedData = sharedData;        }        public void run() {            System.out.println("Running TimeoutRunnable Runnable Start");            long startTime = System.currentTimeMillis();            int secondsToSleep = 1;            int iterationsPerNote = 2;            int iterations = 10;            for(int i=0; i<iterations; i++) { // Sleep for at most 10 seconds                boolean workerRunnableIsFinished = sharedData.getIsFinished(runnable);                if(workerRunnableIsFinished) {                    return;                } else {                    if(i % iterationsPerNote == 0) { // Print a message every 2 iterations                        System.out.println("TimeoutRunnable waiting for workerRunnable...");                    }                }                try { // Sleep for 1 second                    Thread.sleep(secondsToSleep*1000);                } catch (Exception ex) {                    ex.printStackTrace();                }            }            // 5 minutes have passed, kill thread            System.out.println("Killing worker thread for taking too long");            workerThreadToKillIfItTakesTooLong.stop();            HttpGet httpGet = sharedData.getHttpGet(runnable); // MOD            httpGet.abort(); // MOD            sharedData.setIsFinished(runnable, true);            long endTime = System.currentTimeMillis();            System.out.println("Running TimeoutRunnable Runnable End timeInSeconds:"+(endTime-startTime)/1000);        }    }}

Here was the modified output

main: main Startmain: Starting HTTPS Request Threadmain: Starting Timeout Thread1st_: Running HttpRequestRunnable Runner Startmain: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE2nd_: Running TimeoutRunnable Runnable Start2nd_: TimeoutRunnable waiting for workerRunnable...main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE2nd_: TimeoutRunnable waiting for workerRunnable...main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLEmain: workerThread.getState():RUNNABLE timeoutThread.getState():TIMED_WAITINGmain: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE2nd_: TimeoutRunnable waiting for workerRunnable...main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLEmain: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE2nd_: TimeoutRunnable waiting for workerRunnable...main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE2nd_: TimeoutRunnable waiting for workerRunnable...main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLEmain: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE2nd_: Killing worker thread for taking too longmain: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE2nd_: Running TimeoutRunnable Runnable End timeInSeconds:10main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATEDmain: main End timeInSeconds:30