Проблемы с синхронизацией потоков с Apache Mina - PullRequest
1 голос
/ 08 декабря 2009

Я использую 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);
}

Что я делаю не так?

1 Ответ

0 голосов
/ 08 декабря 2009

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

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

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

...