- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在我的应用程序中,有多个 IntentService 根据用户与应用程序的交互以随机间隔与 Tomcat 服务器连接/通信。
我正在为 Http 使用以下 Singleton
public class CustomHttpClient {
private static HttpClient customHttpClient;
/** A private Constructor prevents instantiation */
private CustomHttpClient() {
}
public static synchronized HttpClient getHttpClient() {
if (customHttpClient == null) {
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true);
HttpProtocolParams.setUserAgent(params,"Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; Nexus One Build/FRG83)" +
" AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1");
ConnManagerParams.setTimeout(params, 1000);
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 10000);
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params,schReg);
customHttpClient = new DefaultHttpClient(conMgr, params);
}
return customHttpClient;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
除了当两个 IntentService
同时尝试 Http 或者当一个连接正在进行并且另一个连接已建立时它会给出 connectTimeOut 之外,该类工作正常。 p>
代码中的一个明显改进是用 PoolingClientConnectionManager 替换弃用的
ThreadSafeClientConnManager
。
我应该在此处同步
-> public static synchronized HttpClient getHttpClient()
导致 connectTimeOut 的单例中有什么错误?
最佳答案
Synchronize the PoolingClientConnectionManager or not?
是也不是。如果您希望 getHttpClient()
成为单例(IMO 是个好主意),您必须使其线程安全。这需要 synchronized
。如果没有 synchronized
,两个线程可以同时进入 if block (因为 customHttpClient == null
对两个线程都是 true)并创建两个实例。
但是有更好的(和更快的)方法不用 synchronized
来创建线程安全的单例。我喜欢Singleton Holder例如方法。
但是无论您在这里使用的是什么单例,都不应该出现连接超时。如果您为每个线程使用新的 HttpClient
实例,它也应该可以工作。
如果发生连接超时,则您的线程之一无法在您使用 HttpConnectionParams.setConnectionTimeout(params, 5000);
= 5 秒设置的时间限制内连接到服务器。
这可能有几个原因。例如,如果您的连接缓慢且不稳定,则可能需要更长的时间,因为您的连接可能会中断几秒钟。或者,如果您的服务器由于配置(例如每个 IP 的连接限制)或因为硬件无法处理更多连接而无法处理更多连接,您也会看到此问题。基本上任何阻止 HttpClient
向服务器发送数据包或从服务器接收数据包的事情都会触发该问题。意味着您的问题要么在设备上,要么在网络上,要么在服务器上。
我不知道您的网络设置,但您可以尝试增加超时时间,看看是否有任何效果。 AndroidHttpClient
例如将这些超时设置为 60 秒。如果您使用的是 WiFi 且连接稳定,那么这远远超过要求,但在连接非常弱时也很好。
您还可以检查 AndroidHttpClient
应用的其他设置是否有帮助。
下面AndroidHttpClient
的设置
// Default connection and socket timeout of 60 seconds. Tweak to taste.
private static final int SOCKET_OPERATION_TIMEOUT = 60 * 1000;
// ---------------------------------------------------------------------- //
HttpParams params = new BasicHttpParams();
// Turn off stale checking. Our connections break all the time anyway,
// and it's not worth it to pay the penalty of checking every time.
HttpConnectionParams.setStaleCheckingEnabled(params, false);
HttpConnectionParams.setConnectionTimeout(params, SOCKET_OPERATION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, SOCKET_OPERATION_TIMEOUT);
HttpConnectionParams.setSocketBufferSize(params, 8192);
// Don't handle redirects -- return them to the caller. Our code
// often wants to re-POST after a redirect, which we must do ourselves.
HttpClientParams.setRedirecting(params, false);
// Use a session cache for SSL sockets
SSLSessionCache sessionCache = context == null ? null : new SSLSessionCache(context);
// Set the specified user agent and register standard protocols.
HttpProtocolParams.setUserAgent(params, userAgent);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http",
PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https",
SSLCertificateSocketFactory.getHttpSocketFactory(
SOCKET_OPERATION_TIMEOUT, sessionCache), 443));
ClientConnectionManager manager =
new ThreadSafeClientConnManager(params, schemeRegistry);
return new DefaultHttpClient(manager, params);
要确定您的问题出在哪里,您可以查看您的服务器连接日志并检查设备是否尝试启动连接,如果是,是否存在连接未建立的原因。如果超时时您没有看到任何连接尝试,则很可能是设备或网络问题。
如果您可以访问设备所连接的网络 (=WiFi),您可以使用例如Wireshark由于连接尝试超时的原因。您可以在那里看到设备是否发送连接请求。
最后但同样重要的是,它可能是由您的某些代码引起的。如果您找不到其他解决方案,请尝试使用 HttpURLConnection
实现它,看看是否有帮助。
关于java - 是否同步 PoolingClientConnectionManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12030331/
此问题与 PoolingClientConnectionManager (HttpClient 4.2.5 API) 有关 我在池中最多有 5 个远程连接和一个包含 20 多个 url 的列表,可以从
我有以下使用 PoolingClientConnectionManager 的代码: public static void main(String[] args) { int NoOfSimu
在我的应用程序中,有多个 IntentService 根据用户与应用程序的交互以随机间隔与 Tomcat 服务器连接/通信。 我正在为 Http 使用以下 Singleton public class
我正在使用 Apache DefaultHttpClient与 PoolingClientConnectionManager和 BasicResponseHandler .这些在不同线程之间共享,每个
在 Apache httpclient 4.* 中,为什么所有的方法都被弃用了?如果全部弃用,我们如何有效地使用这个类。 当我执行 PoolingClientConnectionManager.get
PoolingHttpClientConnectionManager 和 PoolingClientConnectionManager 之间有什么区别。为什么 PoolingClientConnect
在我们使用 PoolingClientConnectionManager 4.2.1 的系统上(由于其他依赖项,我们目前无法更新它)。 当有超过一定数量的请求时,我们开始为单个请求获取 SSLPeer
我的网络应用程序在晚上运行作业!遇到问题!它占用了大量内存! 我用命令查找哪个函数占用了java资源! 结果是: [tomcat@uhzd006525 ~]$ jstack 2365
我正在使用 RestClient 连接到远程 JSON API。之前,在 Spring 3.0 中,我使用的是 Commons HTTPClient。我发现由于旧的多线程连接管理器中存在大量锁定,性能
当使用 Apache PoolingClientConnectionManager 时,例如: PoolingClientConnectionManager cm = new PoolingClien
尽管在我的 pom.xml 中没有将其明确引用为依赖项,但此依赖项出现问题。实际的 maven 依赖是: org.apache.httpcomponents ht
使用 Jboss AS7 和 Resteasy 运行默认的万能 key 示例,我完全按照此处的说明操作:https://github.com/resteasy/Resteasy/tree/master
这个问题已经有答案了: Why am I getting a NoClassDefFoundError in Java? (31 个回答) 已关闭 6 年前。 public static void m
我是一名优秀的程序员,十分优秀!