4444import com .rabbitmq .client .SaslConfig ;
4545import com .rabbitmq .client .SaslMechanism ;
4646import com .rabbitmq .client .ShutdownSignalException ;
47+ import com .rabbitmq .client .ThreadFactory ;
4748import com .rabbitmq .client .impl .AMQChannel .BlockingRpcContinuation ;
4849import com .rabbitmq .utility .BlockingCell ;
4950
@@ -61,6 +62,8 @@ final class Copyright {
6162public class AMQConnection extends ShutdownNotifierComponent implements Connection , NetworkConnection {
6263 /** Timeout used while waiting for AMQP handshaking to complete (milliseconds) */
6364 public static final int HANDSHAKE_TIMEOUT = 10000 ;
65+ private Thread mainLoopThread ;
66+ private ThreadFactory threadFactory = new DefaultThreadFactory ();
6467
6568 /**
6669 * Retrieve a copy of the default table of client properties that
@@ -216,7 +219,7 @@ public AMQConnection(ConnectionParams params, FrameHandler frameHandler)
216219 this ._workService = new ConsumerWorkService (params .getExecutor ());
217220 this ._channelManager = null ;
218221
219- this ._heartbeatSender = new HeartbeatSender (frameHandler );
222+ this ._heartbeatSender = new HeartbeatSender (frameHandler , threadFactory );
220223 this ._brokerInitiatedShutdown = false ;
221224
222225 this ._inConnectionNegotiation = true ; // we start out waiting for the first protocol response
@@ -264,7 +267,9 @@ public void start()
264267 }
265268
266269 // start the main loop going
267- new MainLoop ("AMQP Connection " + getHostAddress () + ":" + getPort ()).start ();
270+ MainLoop loop = new MainLoop ();
271+ mainLoopThread = threadFactory .newThread (loop , "AMQP Connection " + getHostAddress () + ":" + getPort ());
272+ mainLoopThread .start ();
268273 // after this point clear-up of MainLoop is triggered by closing the frameHandler.
269274
270275 AMQP .Connection .Start connStart = null ;
@@ -337,7 +342,7 @@ public void start()
337342 int channelMax =
338343 negotiateChannelMax (this .requestedChannelMax ,
339344 connTune .getChannelMax ());
340- _channelManager = instantiateChannelManager (channelMax );
345+ _channelManager = instantiateChannelManager (channelMax , threadFactory );
341346
342347 int frameMax =
343348 negotiatedMaxValue (this .requestedFrameMax ,
@@ -374,8 +379,8 @@ public void start()
374379 return ;
375380 }
376381
377- protected ChannelManager instantiateChannelManager (int channelMax ) {
378- return new ChannelManager (this ._workService , channelMax );
382+ protected ChannelManager instantiateChannelManager (int channelMax , ThreadFactory threadFactory ) {
383+ return new ChannelManager (this ._workService , channelMax , threadFactory );
379384 }
380385
381386 /**
@@ -427,6 +432,23 @@ public void setHeartbeat(int heartbeat) {
427432 }
428433 }
429434
435+ /**
436+ * Makes it possible to override thread factory that is used
437+ * to instantiate connection network I/O loop. Only necessary
438+ * in the environments with restricted
439+ * @param threadFactory
440+ */
441+ public void setThreadFactory (ThreadFactory threadFactory ) {
442+ this .threadFactory = threadFactory ;
443+ }
444+
445+ /**
446+ * @return Thread factory used by this connection.
447+ */
448+ public ThreadFactory getThreadFactory () {
449+ return threadFactory ;
450+ }
451+
430452 public Map <String , Object > getClientProperties () {
431453 return new HashMap <String , Object >(_clientProperties );
432454 }
@@ -485,14 +507,7 @@ private static final int negotiatedMaxValue(int clientValue, int serverValue) {
485507 Math .min (clientValue , serverValue );
486508 }
487509
488- private class MainLoop extends Thread {
489-
490- /**
491- * @param name of thread
492- */
493- MainLoop (String name ) {
494- super (name );
495- }
510+ private class MainLoop implements Runnable {
496511
497512 /**
498513 * Channel reader thread main loop. Reads a frame, and if it is
@@ -636,13 +651,14 @@ public void handleConnectionClose(Command closeCommand) {
636651 _channel0 .quiescingTransmit (new AMQP .Connection .CloseOk .Builder ().build ());
637652 } catch (IOException _) { } // ignore
638653 _brokerInitiatedShutdown = true ;
639- Thread scw = new SocketCloseWait (sse );
640- scw .setName ("AMQP Connection Closing Monitor " +
654+ SocketCloseWait scw = new SocketCloseWait (sse );
655+ Thread waiter = threadFactory .newThread (scw );
656+ waiter .setName ("AMQP Connection Closing Monitor " +
641657 getHostAddress () + ":" + getPort ());
642- scw .start ();
658+ waiter .start ();
643659 }
644660
645- private class SocketCloseWait extends Thread {
661+ private class SocketCloseWait implements Runnable {
646662 private final ShutdownSignalException cause ;
647663
648664 public SocketCloseWait (ShutdownSignalException sse ) {
@@ -789,7 +805,7 @@ public void close(int closeCode,
789805 boolean abort )
790806 throws IOException
791807 {
792- boolean sync = !(Thread .currentThread () instanceof MainLoop );
808+ boolean sync = !(Thread .currentThread () == mainLoopThread );
793809
794810 try {
795811 AMQP .Connection .Close reason =
0 commit comments