Всегда ли требуется отдельный поток записи (в клиенте чтения сокетов/записи файлов)?

У меня есть клиентский код, который читает из сокета (через входной поток) и записывает в файл (через BufferedWriter) в цикле:

dataInStream = new BufferedInputStream(dataSocket.getInputStream());
outputFile = new BufferedWriter(new FileWriter(filename));
byte bytes[] = new byte[64];
Message msg = new Message();
int bytesRead = 0;
while (true) {                
   bytesRead = dataInStream.read(bytes, 0, 64);
   // create a message from the raw data...
   msg.parse(bytes);
   // write it to the file as a String
   outputFile.write(msg.toString());
   outputFile.flush();
}

(упрощенный код для демонстрации общего потока — мне интересно учиться только тогда, когда мне нужно добавить дополнительный поток записи)

В какой момент (с точки зрения скорости передачи данных) мне может понадобиться разделить операцию записи файла на другой поток (т. е. «записывающий») с чем-то вроде ConcurrentLinkedQueue между потоками чтения и записи?

Мои требования к скорости сообщений низкие (т.е. 1400 байт сообщений при макс. ~ 10 в секунду)

Тестовый код, который я запускал для оценки пропускной способности, показал, что он может легко обрабатывать 150 000 байт в секунду. Поскольку скорость передачи данных (какой бы она ни оказалась) постоянна, может ли писатель когда-либо блокироваться достаточно долго, чтобы вызвать потерю данных на считывателе?

Или это просто хорошая практика всегда иметь читательскую и цепочку авторов?


person Steve Larkin    schedule 01.06.2012    source источник


Ответы (1)


В какой момент (по скорости передачи данных) мне может понадобиться разделить операцию записи файла на другой поток (т. е. «запись»)

Вы должны только начинать оптимизировать свой код (усложняя его), когда у вас возникают проблемы с производительностью или когда профилировщик говорит вам, что это хорошая идея.

Или это просто хорошая практика - всегда иметь ветку для чтения и записи?

Это хорошая практика без какой-либо другой информации. Но в вашем случае вы знаете требования к данным, поэтому вам следует делать это только в том случае, если вы ожидаете большой объем пропускной способности или если вы ожидаете, что ввод-вывод будет привязан к диску.

Мои требования к скорости сообщений низкие (т.е. 1400 байт сообщений при макс. ~ 10 в секунду)

Это просто не большая пропускная способность данных, чтобы гарантировать дополнительную сложность кода.

может ли писатель когда-либо блокировать достаточно долго, чтобы вызвать потерю данных в читателе?

В большинстве случаев локальный дисковый ввод-вывод будет быстрее, чем сетевой. Можно столкнуться с этой ситуацией, но я думаю, что это не очень распространено. Ядро дает вам большую буферизацию в сокете, и протокол TCP/IP будет повторно передавать, если вы переполните буферы ядра, так что даже если вы делаете блокировку в течение большого количества времени, вы не будете потерять данные.

person Gray    schedule 01.06.2012
comment
спасибо за молниеносный ответ! Вы подтвердили мои подозрения. (немного паранойи никогда не помешает...) - person Steve Larkin; 01.06.2012