我在Tomcat 8.5中收到以下警告,我不确定是否可以忽略
WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [AppName] appears to have started a thread named [pool-20-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
java.net.SocketInputStream.read(SocketInputStream.java:171)
java.net.SocketInputStream.read(SocketInputStream.java:141)
sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
sun.security.ssl.InputRecord.read(InputRecord.java:503)
sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
它发生在connect
中,如下代码:
URL url = new URL(MY_URL);
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setFixedLengthStreamingMode(out.length);
http.setRequestProperty("Content-Type", "application/json");
http.connect();
try (OutputStream os = http.getOutputStream()) {
os.write(out);
}
我应该在关闭InputStream
之后添加一个finally:
http.getInputStream().close();
还是应该将此代码升级/转换为使用URIBuilder
和HttpHost
?
编辑
使用Spring的@Scheduled
答案 0 :(得分:1)
您正在Tomcat中使用@Scheduled
来生成线程。您必须确保ServletContext
被破坏时这些线程将完成,例如取消部署WAR后,Tomcat会警告您。 HTTP请求代码无关,因为URLConnection
不会启动新线程来执行请求。
使Tomcat满意的一种方法是使用守护程序线程,如this answer中所述。可以使用自定义taskScheduler
bean:
@Configuration
@EnableScheduling
public class TaskConfiguration {
@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
return Executors.Executors.newFixedThreadPool(4,
new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}
});
}
}