Чтение n байтов атомарно без блокировки - PullRequest
0 голосов
/ 14 февраля 2020

Я только что задал вопрос о том, почему не работает моя нить. Это закончилось тем, что readLine() заблокировал мой поток, прежде чем флаг завершения работы мог быть распознан. Это было легко исправить, проверив ready() перед вызовом readLine().

Однако теперь я использую DataInputStream для последовательного выполнения следующих действий:

int x = reader.readInt();
int y = reader.readInt();
byte[] z = new byte[y]
reader.readFully(z);

I знаю, что я мог бы реализовать свою собственную буферизацию, которая проверяла бы флаг запущенного файла при загрузке буфера. Но я знаю, что это было бы утомительно. Вместо этого я мог позволить буферизовать данные в классе InputStream и подождать, пока у меня прочитаются мои n байты, прежде чем выполнять неблокирующее чтение - поскольку я знаю, сколько мне нужно прочитать.

  • 4 байт для первого целого числа
  • 4 байт для второго целого числа y
  • и y байт для z байтового массива.

Вместо использования ready() для проверки, есть ли строка в буфере, есть ли какой-нибудь эквивалент ready(int bytesNeeded)?

Ответы [ 3 ]

0 голосов
/ 14 февраля 2020

Вы можете использовать InputStream.available(), чтобы получить оценку количества байтов, которые можно прочитать. Цитирование Javado c:

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

Другими словами, если available() возвращает n, вы знаете, что можете безопасно вызвать read(n) без блокировки. Обратите внимание, что, как утверждает Javado c, возвращаемое значение является оценочным. Например, InflaterInputStream.available () всегда будет возвращать 1, если EOF не достигнут. Проверьте документацию подкласса InputStream, который вы будете использовать, чтобы убедиться, что он соответствует вашим потребностям.

0 голосов
/ 14 февраля 2020

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

0 голосов
/ 14 февраля 2020

Метод available() возвращает количество байтов во внутреннем буфере InputStream s.

Итак, можно сделать что-то вроде:

while (reader.available() < 4) checkIfShutdown();
reader.readInt();
...