我使用的是Apache HttpClient 4.3.6,而且我在一个特定的实例中很难使用它。
通常,我的所有HttpPost调用都在一个主线程中,并且是串行发生的。但是,有一个实例,一旦发生特定类型的HttpPost,我需要启动一个侧线程来监控它。此侧线程会定期尝试连接到服务器以查看它是否仍然处于运行状态。如果与服务器的连接断开,我需要在main中断()连接,以便它不会被卡住,直到超时发生(我可以合理地进行一个可以采取的操作) 45分钟即可完成。)
我在main的开头设置了一个PoolingHttpClientConnectionManager和一个CloseableHttpClient,然后我有一个send方法,main和side thread都用来设置方法本地的HttpPost对象。但是,send方法的side thread实例的client.execute(httpPost)局部变量结果以某种方式被分配给send方法的主线程实例中的局部变量result。他们越过了。我过去几个小时都在四处搜寻,但我找不到任何解决办法。
编辑:添加了示例代码。不得不通过将各种东西改为使用类的基本变量来混淆公司的东西,所以请原谅一些拼写错误/在此期间的任何事情。
类变量:
CloseableHttpClient client;
HttpPost longHttpPost;
boolean diePlz = false;
主要:
clientPool = new PoolingHttpClientConnectionManager();
clientPool.setMaxTotal(20);
clientPool.setDefaultMaxPerRoute(20);
client = HttpClients.custom().setConnectionManager(clientPool).build();
//Lots of logic here to set up things to be 'send()'ed
发送方式:
private String send(String message, boolean longCall){
RequestConfig.Builder requestConfig = RequestConfig.custom();
requestConfig.setConnectTimeout(10000);
String url = "http://" + ip + ":" + port + "/connector";
HttpPost httpPost;
if(longCall){
httpPost = longHttpPost = new HttpPost(url);
} else {
httpPost = new HttpPost(url);
}
httpPost.setConfig(requestConfig.build());
httpPost.setHeader("Content-Type", "application/xml");
httpPost.setHeader("charset", "UTF-8");
httpPost.setEntity(getEntity(message)); //getEntity() is a local method that overrides AbstractHttpEntity
try {
if(longCall && !threadRunning){
diePlz = false;
ConnectionCheck watcher = new ConnectionCheck();
watcher.start();
}
//httpReponse is what seems to get crossed between invocations of send()
CloseableHttpResponse httpResponse = client.execute(longCall ? longHttpPost : httpPost);
//more stuff here to work with response
} catch (Exception e) {
LOG.error(e, e);
return null;
} finally {
if(longCall){
longHttpPost.releaseConnection();
} else {
httpPost.releaseConnection();
}
}
}
主类中的嵌套线程类:
private class ConnectionCheck extends Thread implements Runnable, Serializable {
@Override
public void run(){
threadRunning = true;
try{Thread.sleep(5000);}catch(Exception e){LOG.error(e, e);}
boolean registerReturn = register(false); //this calls send()
if(registerReturn){
String response = checkStatus(); //this calls send()
if(response == null){ //if the connection we're watching drops...
if(longHttpPost != null){
longHttpPost.abort(); //...then kill it
}
} else {
while(response != null && !diePlz){
try {
Thread.sleep(5000);
} catch (Exception e){
LOG.error(e, e);
register(true);
threadRunning = false;
return;
}
response = checkStatus();
if(response == null){
if(longHttpPost != null){
longHttpPost.abort();
}
}
}
register(true); //this calls send()
threadRunning = false;
}
} else {
register(true); //this calls send()
threadRunning = false;
}
}
}