Повторное использование OutputStream Chronicle Bytes

Я использую сторонний двоичный кодировщик, который принимает OutputStream. Я получаю OutputStream из метода writeMarshallable Marshallable, подобного этому:

public void writeMarshallable(WireOut wire) {
    OutputStream outputStream = wire.bytes().outputStream();
    // third party code gets the outputStream, etc.
}

Реализация wire.bytes().outputStream() создает новый поток StreamingOutputStream при каждом вызове, чего я надеюсь избежать (лишнее выделение объектов, когда базовые байты не имеют фактически изменилось).

Тем не менее, я думаю о том, чтобы сохранить WeakReference для данного значения wire.bytes() и проверить, идентична ли предоставленная ссылка на значение (т.е. ==) ранее предоставленному значению:

private WeakReference<Bytes<?>> priorBytesRef = new WeakReference<>(null);

public void writeMarshallable(WireOut wire) {
    Bytes<?> bytes = wire.bytes();
    if (bytes != priorBytesRef.get()) {
        priorBytesRef = new WeakReference<>(bytes);
        thirdPartyEncoder = EncoderFactoryExample.from(bytes.outputStream());
    }
    // utilize thirdPartyEncoder, etc.
}

Итак, мой вопрос: является ли это разумным подходом или у вас есть более целесообразный способ?

Благодарность!!


person A. Oswald    schedule 22.12.2016    source источник


Ответы (1)


Я предлагаю использовать ThreadLocal для сохранения файла StreamingOutputStream.

static final ThreadLocal<StreamingOutputStream> bosTL = ThreadLocal.withInitial(StreamingOutputStream::new);

public void writeMarshallable(WireOut wire) {
    OutputStream out = bosTL.get().init(wire.bytes());
    // utilize thirdPartyEncoder, etc.
}
person Peter Lawrey    schedule 22.12.2016
comment
Если распределение Marshallable осуществляется с помощью ServiceWrapper (т. е. это одиночное распределение, управляемое ServiceWrapper), необходим ли ThreadLocal или я могу просто уйти с BytesOutputStream членом класса? Еще раз спасибо, Пит! - person A. Oswald; 26.12.2016
comment
@A.Oswald A.Oswald ThreadLocal нужен только в том случае, если вы не можете быть уверены, что только один поток будет использовать поток. - person Peter Lawrey; 26.12.2016
comment
Если у меня нет ни версии, ни зависимости, я боюсь, что существует конфликт байтов type, предоставляемых Chronicle-Queue (net.openhft.chronicle.bytes), и того, что требует API BytesOutputStream ( net.openhft.lang.io). Я получал BytesOutputStream из OpenHFT/Java-Lang (v 6.8.2). - person A. Oswald; 27.12.2016
comment
Пит: код не компилируется; см. мой комментарий выше о несовместимости типа Bytes. Какие-нибудь мысли? Благодарность - person A. Oswald; 03.01.2017
comment
@A.Oswald А.Освальд Я предлагаю избегать Java-Lang, так как это более старая библиотека. Я предлагаю использовать Chronicle-Bytes, который использует Chronicle-Queue. - person Peter Lawrey; 03.01.2017
comment
Сначала я чувствовал себя немного глупо, но после проверки BytesOutputStream (в настоящее время) не существует в Chronicle-Bytes. Не могли бы вы перепроверить это? - person A. Oswald; 03.01.2017
comment
@A.Oswald A.Oswald Извините, это моя ошибка, вы правы, класс был переименован. Не могли бы вы проверить последний снимок для StreamingOutputStream. Если вас это устраивает, я могу выпустить его. - person Peter Lawrey; 03.01.2017
comment
Вы предлагаете вызывать init StreamingOutputStream при каждом вызове? Мне не очень нравится название метода, но все остальное выглядит хорошо (и у меня нет лучшего предложения). Спасибо, что изучили это! Ps: пример кода нужно будет изменить с bytes на то, что вы в конечном итоге вызываете (в настоящее время init) - person A. Oswald; 03.01.2017
comment
@ А.Освальд Да, спасибо за исправление. Я использую init, так как это имя для конструкторов, на уровне байтового кода конструкторы называются <init> - person Peter Lawrey; 03.01.2017