关于我们如何杀死已发出http post请求并等待响应的线程的任何建议。我希望从另一个并行运行的线程中杀死这个线程,然后才能收到请求的任何响应。我建议关闭或中止http post请求但没有锻炼,有人可以建议我们如何在这种情况下中止http请求或以任何其他方式实现此目的。
答案 0 :(得分:2)
在等待服务器响应时阻止发出请求的线程。如果你进行线程转储并看到它,它将在一些read()方法中,但不在Thread.sleep上。所以调用interrupt()不会产生影响(除非它是InterruptibleChannel)。 您是否可以访问发出POST请求的套接字或输出流?如果是这样,您可以关闭它,这将带来异常的读取等待。 你有一个可以提出的代码示例吗?
答案 1 :(得分:1)
Helloo大家,终于得到了这个关闭套接字的想法实现和工作。下面是我试过的片段。
我的请求主题
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);
}
}
取消线程
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());
}
}
共享对象
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()
}
}
主类
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();
}
}
}
我同意它的未清洁代码,但它有效。它导致以下异常并杀死线程。
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)
感谢所有努力帮助我的人。
答案 2 :(得分:0)
我试图解决同一件事。我编写了一个HTTP Request Runnable,它花了20秒钟超时并在一个线程(第一个线程)上执行。我在一个单独的线程(第二个线程)上编写了一个Timeout Runnable,该线程本应在10秒后中断/停止第一个线程。对于主线程中的每一秒(总共3个线程),我打印了线程的状态,发现第一个线程一直在运行。
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);
}
}
}
这是输出
main: main Start
main: Starting HTTPS Request Thread
main: Starting Timeout Thread
1st_: Running HttpRequestRunnable Runner Start
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
2nd_: Running TimeoutRunnable Runnable Start
2nd_: TimeoutRunnable waiting for workerRunnable...
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
2nd_: TimeoutRunnable waiting for workerRunnable...
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
2nd_: TimeoutRunnable waiting for workerRunnable...
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
main: workerThread.getState():RUNNABLE timeoutThread.getState():TIMED_WAITING
2nd_: TimeoutRunnable waiting for workerRunnable...
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
main: workerThread.getState():RUNNABLE timeoutThread.getState():TIMED_WAITING
2nd_: TimeoutRunnable waiting for workerRunnable...
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
main: workerThread.getState():RUNNABLE timeoutThread.getState():TIMED_WAITING
2nd_: Killing worker thread for taking too long
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
2nd_: Running TimeoutRunnable Runnable End timeInSeconds:10
main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATED
main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATED
main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATED
main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATED
main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATED
main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATED
main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATED
main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATED
main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATED
main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATED
main: workerThread.getState():RUNNABLE timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: main End timeInSeconds:30
我使用SharedData类来保存两个线程所需的信息。通过添加终止线程(即HttpGet)所需的额外信息,我可以让监视线程执行实际上终止线程(即调用httpGet.abort)所需的一切。这是修改后的代码(修改后的行以// 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);
}
}
}
这是修改后的输出
main: main Start
main: Starting HTTPS Request Thread
main: Starting Timeout Thread
1st_: Running HttpRequestRunnable Runner Start
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
2nd_: Running TimeoutRunnable Runnable Start
2nd_: TimeoutRunnable waiting for workerRunnable...
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
2nd_: TimeoutRunnable waiting for workerRunnable...
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
main: workerThread.getState():RUNNABLE timeoutThread.getState():TIMED_WAITING
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
2nd_: TimeoutRunnable waiting for workerRunnable...
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
2nd_: TimeoutRunnable waiting for workerRunnable...
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
2nd_: TimeoutRunnable waiting for workerRunnable...
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
2nd_: Killing worker thread for taking too long
main: workerThread.getState():RUNNABLE timeoutThread.getState():RUNNABLE
2nd_: Running TimeoutRunnable Runnable End timeInSeconds:10
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: workerThread.getState():TERMINATED timeoutThread.getState():TERMINATED
main: main End timeInSeconds:30