В момента, в който всички данни във входния поток бъдат изразходвани, връзката се освобождава автоматично и се добавя към пула за връзки. Базовата връзка на сокет не се освобождава, като се предполага, че връзката ще бъде използвана повторно в близко бъдеще. Добра практика е да извикате disconnect
в finally
блок, тъй като той се грижи за освобождаването на връзката в случай на exceptions
.
Ето внедряването на метода за четене на FixedLengthInputStream:
@Override public int read(byte[] buffer, int offset, int count) throws IOException {
Arrays.checkOffsetAndCount(buffer.length, offset, count);
checkNotClosed();
if (bytesRemaining == 0) {
return -1;
}
int read = in.read(buffer, offset, Math.min(count, bytesRemaining));
if (read == -1) {
unexpectedEndOfInput(); // the server didn't supply the promised content length
throw new IOException("unexpected end of stream");
}
bytesRemaining -= read;
cacheWrite(buffer, offset, read);
if (bytesRemaining == 0) {
endOfInput(true);
}
return read;
}
Когато променливата bytesRemaining стане 0, endOfInput се извиква, което допълнително ще извика метод за освобождаване с истински параметър, което ще гарантира, че връзката е обединена.
protected final void endOfInput(boolean reuseSocket) throws IOException {
if (cacheRequest != null) {
cacheBody.close();
}
httpEngine.release(reuseSocket);
}
Ето release внедряване на метода. Последната проверка if гарантира дали връзката трябва да бъде затворена или добавена към пула за връзки за повторно използване.
public final void release(boolean reusable) {
// If the response body comes from the cache, close it.
if (responseBodyIn == cachedResponseBody) {
IoUtils.closeQuietly(responseBodyIn);
}
if (!connectionReleased && connection != null) {
connectionReleased = true;
// We cannot reuse sockets that have incomplete output.
if (requestBodyOut != null && !requestBodyOut.closed) {
reusable = false;
}
// If the headers specify that the connection shouldn't be reused, don't reuse it.
if (hasConnectionCloseHeader()) {
reusable = false;
}
if (responseBodyIn instanceof UnknownLengthHttpInputStream) {
reusable = false;
}
if (reusable && responseBodyIn != null) {
// We must discard the response body before the connection can be reused.
try {
Streams.skipAll(responseBodyIn);
} catch (IOException e) {
reusable = false;
}
}
if (!reusable) {
connection.closeSocketAndStreams();
connection = null;
} else if (automaticallyReleaseConnectionToPool) {
HttpConnectionPool.INSTANCE.recycle(connection);
connection = null;
}
}
}
Забележка: Преди това бях отговорил на няколко SO въпроса, свързани с HttpURLConnection, което може да ви помогне да разберете основната реализация. Ето връзките: Link1 и Връзка2.
person
Manish Mulimani
schedule
11.07.2014
Connection
наclose
. - person hgoebl   schedule 07.07.2014