Проблемы с синхронизацией потоков с Apache Mina

Я использую Apache Mina 1.1.7 и Java 1.6. Сервер отправляет клиенту последовательность из трех сообщений в цикле. Иногда два набора сообщений перекрываются. Например, я ожидаю:

++ recv: MSGHEAD 
++ recv: message body 1
++ recv: .

++ recv: MSGHEAD 
++ recv: message body 2
++ recv: .

но вместо этого я получаю это:

++ recv: MSGHEAD
++ recv: MSGHEAD 
++ recv: message body 1
++ recv: .
++ recv: message body 2
++ recv: .

Вот моя конфигурация сервера:

    SocketAcceptor acceptor = new SocketAcceptor();
    SocketAcceptorConfig config = new SocketAcceptorConfig();
    config.setThreadModel(ThreadModel.MANUAL);
    if (true) {
        SSLContextFactory factory = new SSLContextFactory();
        config.getFilterChain().addLast("sslFilter", new SSLFilter(factory.getInstance(true)));
    }

    System.out.println(config.getFilterChain().toString());
    config.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")) ));
    config.getFilterChain().addLast("to-message", new ToMessageIoFilter());

    config.getSessionConfig().setReuseAddress( true );
    config.getSessionConfig().setTcpNoDelay(true);
    acceptor.bind( new InetSocketAddress(PORT), new MinaServerHandler(new MinaConnectionFactory()), config );
}

Вот как я отправляю последовательность сообщений:

public  void sendMessage(String msg) throws IOException {
    synchronized(session){
        writeLine("MSGHEAD");
        writeLine(msg);
        writeLine(".");
    }
}

private void writeLine(String line) {
    WriteFuture w=session.write(line);
}

Что я делаю неправильно?


person yang    schedule 07.12.2009    source источник


Ответы (1)


Если три потока находятся в циклах по sendMessage(), то можно ожидать, что они будут выводить строки, иногда чередующиеся, а иногда - нет. Какое поведение вы описываете.

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

Самый простой способ решить эту проблему - удалить синхронизированный оператор и сделать sendMessage() синхронизированный метод. Хотя это может быть не очень быстро.

person dlamblin    schedule 08.12.2009