我的代码如下:
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)
我使用Java 8和JeroMQ 0.3.5-SNAPSHOT
答案 0 :(得分:0)
ZMQ套接字不是线程安全的。您在一个线程中创建套接字然后在另一个线程中使用它的能力有限,但我猜测看不见的代码将分支到多个线程,所有线程都试图同时使用套接字。那是ZMQ禁忌。通常,您应该在他们将要使用的线程中创建套接字。
ZMQ上下文是线程安全。