Java 在执行同步调用时,许多ReaderRunnable线程仍在运行

Java 在执行同步调用时,许多ReaderRunnable线程仍在运行,java,okhttp,Java,Okhttp,使用OkHttpClient 3.6.0 对于相同的SSL证书和主机,我有一个100k通知流要发送到APN。应用程序读取此流,对其进行排队,并使用包含800个线程的executor服务进行同步调用,如下所示: client.newCall(请求).execute() 在过去的几天里,我看到我们正在创建大量的连接(从而创建了大量ReaderRunnable线程)。当连接计数较高时,我通过查看连接计数和相应的堆栈跟踪来了解这一点。我看到很多来自ReaderRunnable的okhttpapi.pus

使用OkHttpClient 3.6.0

对于相同的SSL证书和主机,我有一个100k通知流要发送到APN。应用程序读取此流,对其进行排队,并使用包含800个线程的executor服务进行同步调用,如下所示:

client.newCall(请求).execute()

在过去的几天里,我看到我们正在创建大量的连接(从而创建了大量ReaderRunnable线程)。当连接计数较高时,我通过查看连接计数和相应的堆栈跟踪来了解这一点。我看到很多来自ReaderRunnable的
okhttpapi.push.apple.com
线程

"OkHttp api.push.apple.com" #84247 daemon prio=5 os_prio=0 tid=0x00002b3a7c022800 nid=0xefd3 runnable [0x00002b29f5e1e000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
    at sun.security.ssl.InputRecord.read(InputRecord.java:503)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
    - locked <0x00002b34f69a7728> (a java.lang.Object)
    at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:930)
    at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
    - locked <0x00002b34f69a7f48> (a sun.security.ssl.AppInputStream)
    at okio.Okio$2.read(Okio.java:138)
    at okio.AsyncTimeout$2.read(AsyncTimeout.java:236)
    at okio.RealBufferedSource.request(RealBufferedSource.java:66)
    at okio.RealBufferedSource.require(RealBufferedSource.java:59)
    at okhttp3.internal.http2.Http2Reader.nextFrame(Http2Reader.java:95)
    at okhttp3.internal.http2.Http2Connection$ReaderRunnable.execute(Http2Connection.java:566)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.lang.Thread.run(Thread.java:745)



2018-03-20 19:58:02 - OkHttpClient Connection Pool Count is 336
2018-03-20 19:59:02 - OkHttpClient Connection Pool Count is 12182
2018-03-20 20:00:07 - OkHttpClient Connection Pool Count is 17081
2018-03-20 20:01:02 - OkHttpClient Connection Pool Count is 19700
2018-03-20 20:02:01 - OkHttpClient Connection Pool Count is 10 

您是否可以包含更多的示例代码以使其可复制。理想情况下,只有一个文件可以建立连接,并且可以由其他人运行,或者至少验证您只有800个线程的语句。如果您的应用程序逻辑中有错误,我们将不知道,因为您刚刚描述了它。此外,请使用3.10进行测试,以防它与以前修复的错误有关。另外,请看一下使用EventListener,它可以告诉您关于连接建立和获取的情况(例如,可能已被重用)。感谢您的回复。我将更新到3.10并再次测试。在#1上,您知道是否有任何方法可以查看
MAX#u CONCURRENT_STREAMS
的值。我只能看到框架日志的日志记录。我怀疑只有通过reflectionI升级到3.10。我用日志定制了okhttp客户端,以找出连接不被重用的原因。结果是SSLSocketFactory不执行对象相等,因此创建了新的连接。现在我正在重用这个对象,不再看到这个问题了。
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS);
builder.connectionPool(new ConnectionPool(HTTP_CLIENT_MAX_CONNECTIONS, 10, TimeUnit.MINUTES));