Блок синхронизации внутри метода обратного вызова - PullRequest
0 голосов
/ 28 августа 2018

Я использую Apache Mina в одном из моих проектов. DoDecode () CumulativeProtocolDecoder вызывается при каждом получении фрагмента данных. Я соединяю эти куски вместе, пока не получу специальный символ в конце строки. Поэтому я начинаю конкатенацию, когда получаю $ в качестве первого символа, и заканчиваю конкатенацию, когда получаю еще один символ $.

Я хочу синхронизировать часть конкатенации, чтобы избежать возможных непреднамеренных конкатенаций.

Путем инкапсуляции блока конкатенации с помощью synchronized () я могу сделать эту операцию безопасной для потока, но Мой вопрос: пока один поток занят выполнением конкатенации, а другой поток вызывает doDecode () с новыми данными, будут ли новые информация, предоставляемая в качестве аргумента для doDecode (), будет потеряна, потому что синхронизированный блок занят, или он будет ждать и сохранять кешированный аргумент, пока синхронизированный блок снова не станет доступным?

@Override
    protected boolean doDecode(IoSession ioSession, IoBuffer ioBuffer, ProtocolDecoderOutput protocolDecoderOutput) throws Exception {
        System.out.println("inside decoder");

        try {
            IoBuffer data = (IoBuffer) ioBuffer;
            // create a byte array to hold the bytes
            byte[] buf = new byte[data.limit()];

            System.out.println("REPSONSE LENGTH: "+ data.limit());
            // pull the bytes out
            data.get(buf);
            // look at the message as a string
            String messageString = new String(buf);

            synchronized (messageString) {
                //do concatenatoin operatoins and other stuff
            }

        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

1 Ответ

0 голосов
/ 29 августа 2018

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

Каждый поток, вызывающий doDecode, будет иметь свою собственную копию аргументов метода, поэтому вы можете быть уверены, что ни один аргумент не будет изменен между .

Я предполагаю, объединение этих кусков означает сохранение их в некотором поле члена вашего Decoder класса.

В этом случае вы, вероятно, хотите выполнить синхронизацию на поле. Например:

private final Object lock = new Object();

@Override
protected boolean doDecode(IoSession ioSession, IoBuffer ioBuffer, ProtocolDecoderOutput protocolDecoderOutput) throws Exception {

    // ...
    synchronized (this.lock) {
        // do concatenation operations and other stuff
    }
    // ...
}

Я просто не уверен, является ли хорошей практикой синхронизация внутри компонента инфраструктуры, который, вероятно, предназначен для одновременной обработки запросов.

...