Мотивация по этому вопросу Я запускаю огромный продукт, который работает на очень дорогом оборудовании. Выключение его для целей тестирования невозможно, а также не создает плохую банку в производственной среде. Мне нужно быть как можно увереннее до почти, чтобы я не испортил производственную среду.ScheduledExecutorService использование и очистка заблокированного гнезда instream
Мне нужно, чтобы приведенный ниже код был рассмотрен по очевидным проблемам, прежде чем запускать его на этапе настройки (что так дорого).
Задача У меня есть приложение на основе сокетов, иногда клиенты не отправляют запрос CloseConnection явно. И иногда IOException не возникает, там, удерживая потоки при блокировании вызова readObject
.
Мне нужно закрыть эту тему, закрыв соединение после таймаута. Если я получаю новый запрос с сервера, время ожидания обновляется.
Таким образом, вы будете видеть 3 части ниже
- инициализирующий
- readObject вызов в то время как (истинный) цикл, и запланированное обслуживание сброса
- фактическое закрытие Instream
Код
У меня есть ru рекомендуется использовать ScheduledExecutorService вместо Timer/TimerTask.
class StreamManager {
....
private ScheduledExecutorService activityTimeOut = Executors
.newSingleThreadScheduledExecutor();
private CloseConnectionOnTimeOut closeOnTimeOut = new CloseConnectionOnTimeOut();
....
public void initialize(Socket newClientSocket, ObjectInputStream newInputStream,
ObjectOutputStream newOutputStream, ThreadMonitor newThreadMonitor) {
....
closeOnTimeOut.setInputStream(myInputStream);
activityTimeOut.scheduleAtFixedRate(closeOnTimeOut, 0, Globals.INACTIVITY_TIME_OUT,
TimeUnit.MILLISECONDS);
}
public void run() {
....
while (true) {
try {
AMessageStrategy incomingCommand = (AMessageStrategy) myInputStream
.readObject();
activityTimeOut.shutdown();
activityTimeOut.scheduleAtFixedRate(closeOnTimeOut, 0,
Globals.INACTIVITY_TIME_OUT, TimeUnit.MILLISECONDS);
....
}
....
}
class CloseConnectionOnTimeOut implements Runnable {
private ObjectInputStream myInputStream;
public CloseConnectionOnTimeOut() {
}
public void setInputStream(ObjectInputStream myInputStream) {
this.myInputStream = myInputStream;
}
public void run() {
try {
myInputStream.close();
myOutputStream.close();
clientSocket.close();
log.info("Time out occured for client, closed connection forcefully.") ;
} catch (IOException e) {
e.printStackTrace();
log.fatal("Time out has occured, yet unable to clean up client connection. Keep a watch out on \"Size of clientStreamQ\"");
}
}
}
Edit: Просто протестировали меньшее применение, и это, кажется, работает. Мне все еще нужна ваша обратная связь.
Редактировать снова:
Я изменил код ниже в соответствии с уведомлением.
Инициализация
private ScheduledExecutorService activityTimeOut = Executors
.newSingleThreadScheduledExecutor();
private Future<Void> timeoutTask ;
private CloseConnectionOnTimeOut closeOnTimeOut = new CloseConnectionOnTimeOut();
Удалены этот код
closeOnTimeOut.setInputStream(myInputStream);
activityTimeOut.scheduleAtFixedRate(closeOnTimeOut, 0, Globals.INACTIVITY_TIME_OUT,
TimeUnit.MILLISECONDS);
Заменено до и после readObject
timeoutTask = (Future<Void>) activityTimeOut.scheduleAtFixedRate(
closeOnTimeOut.setInputStream(myInputStream), 0,
Globals.INACTIVITY_TIME_OUT, TimeUnit.MILLISECONDS);
AMessageStrategy incomingCommand = (AMessageStrategy) myInputStream
.readObject();
timeoutTask.cancel(true) ;
На Cleanup
activityTimeOut.shutdown() ;
спасибо. Я добавил измененный код, пожалуйста, проверьте еще раз. И да, мне нужно будет протестировать его на этапе, прежде чем я его выпущу. Одно изменение, однако, я создал объект CloseConneciton раньше, чтобы избежать накопления памяти, является ли это хорошей задачей? – Siddharth