2

次のようなコードがあります。

public void handleRequests() {
    ZMQ.Poller items = new ZMQ.Poller(1);
    items.register(clientEndpoint, ZMQ.Poller.POLLIN);
    while (!Thread.currentThread().isInterrupted()) {
        byte[] message;
        items.poll();  // this is the line that throws exception.
        if (items.pollin(0)) {
            message = clientEndpoint.recv(0);
        }
    }
}

直接呼び出すと正常に動作します:

foo.handleRequests();

ただし、新しいスレッドで実行すると、アサーション エラーで定期的に失敗します。

final Runnable listener = worldviewServer::handleRequests;
Executors.newSingleThreadExecutor().execute(listener);

取得したスタック トレースを以下に示します。

Exception in thread "pool-6-thread-1" java.lang.AssertionError
at zmq.Mailbox.recv(Mailbox.java:113)
at zmq.SocketBase.process_commands(SocketBase.java:820)
at zmq.SocketBase.getsockopt(SocketBase.java:258)
at zmq.PollItem.readyOps(PollItem.java:107)
at zmq.ZMQ.zmq_poll(ZMQ.java:708)
at zmq.ZMQ.zmq_poll(ZMQ.java:600)
at org.zeromq.ZMQ$Poller.poll(ZMQ.java:1618)
at org.zeromq.ZMQ$Poller.poll(ZMQ.java:1592)
at com.tracelink.worldview.server.Head.handleRequests(Head.java:68)
at com.tracelink.worldview.server.WorldviewServer.handleRequests(WorldviewServer.java:236)
at com.tracelink.worldview.server.fsm.EnablingAction$$Lambda$12/404648734.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

JeroMQ 0.3.5-SNAPSHOT で Java 8 を使用しています

4

1 に答える 1

0

ZMQ ソケットはスレッドセーフではありません。あるスレッドでソケットを作成し、それを別のスレッドで使用する機能は限られていますが、目に見えないコードが複数のスレッドに分岐し、すべてが同時にソケットを使用しようとしていると推測しています。それはZMQのノーノーです。一般に、使用されるスレッドでソケットを作成する必要があります。

ZMQ コンテキストスレッドセーフです。

于 2015-06-03T22:10:07.067 に答える