多线程调用Solace会话SendRequest()阻塞,能否同会话并发同步请求?
Great question—this is a super common pitfall when working with Solace's request/reply pattern using a single session. Let's break down why you're seeing this behavior and how to fix it.
Why Your Current Setup is Serial
When you use Solace's synchronous sendRequest() with a non-zero timeout, the method blocks the calling thread until it receives a reply or hits the timeout. That means in the same thread, each subsequent sendRequest() call can't run until the previous one completes. This is intentional default behavior to simplify basic request/reply flows, but it doesn't work for concurrent requests in the same thread.
How to Send Concurrent Requests (While Staying Synchronous in the Same Thread)
The good news is you can absolutely do this—you just need to switch to asynchronous request sending (timeout = 0) and use futures or callbacks to track replies, then wait for all of them in your main thread. Here's how it works:
Use Asynchronous Send with Futures
Instead of blocking on eachsendRequest(), fire off all your requests asynchronously (timeout = 0) and useCompletableFuture(or similar) to capture each reply. Then, in your main thread, wait for all futures to resolve—this keeps everything synchronized in the same thread while letting the requests send in parallel.Example code (Java):
// Assume you already have an established Solace session List<CompletableFuture<SolMessage>> replyFutures = new ArrayList<>(); // Send first request asynchronously CompletableFuture<SolMessage> future1 = new CompletableFuture<>(); session.sendRequest(requestMsg1, 0, new SolReplyCallback() { @Override public void onReply(SolMessage reply) { future1.complete(reply); } @Override public void onException(SolException ex) { future1.completeExceptionally(ex); } }); replyFutures.add(future1); // Send second request immediately (no need to wait for first reply) CompletableFuture<SolMessage> future2 = new CompletableFuture<>(); session.sendRequest(requestMsg2, 0, new SolReplyCallback() { @Override public void onReply(SolMessage reply) { future2.complete(reply); } @Override public void onException(SolException ex) { future2.completeExceptionally(ex); } }); replyFutures.add(future2); // Wait for all replies in the same thread (synchronous wait) for (CompletableFuture<SolMessage> future : replyFutures) { try { SolMessage reply = future.get(); // Process your reply here } catch (InterruptedException | ExecutionException e) { // Handle errors (timeout, connection issues, etc.) e.printStackTrace(); } }Alternative: Session Pools (Less Ideal)
If you really want to stick with synchronoussendRequest()calls, you could create a pool of Solace sessions. Each request uses a different session, so you can callsendRequest()on multiple sessions in sequence (in the same thread) and they'll send in parallel. However, this uses more resources (each session has its own connection overhead) and is less efficient than the async+futures approach, so it's not recommended unless you have specific constraints.
Key Takeaways
- A single Solace session will process synchronous
sendRequest()calls serially in the same thread because each call blocks. - The best approach for concurrent requests in the same thread is to use async sends with futures/callbacks, then wait for all replies synchronously.
- This keeps your thread synchronized while leveraging Solace's ability to handle multiple in-flight requests on a single session.
内容的提问来源于stack exchange,提问作者e-master

