Ittai
Ittai

Reputation: 5915

Spring and Multithreading

I need to start a variable number of threads which in turn each start a varying number of threads (i.e. i threads where the Ith thread needs to start Ki threads) in a spring application.
assuming each of the "I threads" contains an inner class which is autowired how will I generate those instances? So I have an A bean which needs to somehow generate I instances of a bean which needs to be spring managed to satisfy its dependencies.

I've written a short sample code of what I think is the base for my solution and I've marked the code I'm not sure how to write by ???:

@Component
public class MasterOrchestrator {    
 public void do(List<DataObjWrapper> list){
    ExecutorService es = Executors.newFixedThreadPool(list.size());
    for (DataObjWrapper dataObjWrapper : list){
        es.submit(???);
    }
 }    
}
@Component
public class ThreadWorkerI implements Runnable{    
    private int numThreadsForMessageType;
    private int numRunsForMessageType;
    private DataObj dataObj;
        public ThreadWorkerI(int numThreadsForMessageType, int numRunsForMessageType, DataObj dataObj){
        this.numThreadsForMessageType = numThreadsForMessageType;
        this.numRunsForMessageType = numRunsForMessageType;
        this.dataObj = dataObj;
    }
        @Autowired
    private JmsTemplate jmsTemplate;   
    public void run(){  
        ExecutorService es = Executors.newFixedThreadPool(numThreadsForMessageType);
        for (int i=0;i<numRunsForMessageType;i++){
            es.submit(new ActualWorker(i));
        }       
    }

    private class ActualWorker implements Runnable{
        private int numRun;
        private ActualWorker(int numRun){
            this.numRun = numRun;
        }
        public void run(){
            //send message using the jmsTemplate the dataObj and numRun
        }
    }
}

DatObjWrapper contains amongst other members the numThreadsForMessageType, numRunsForMessageType and dataObj.

Upvotes: 1

Views: 7458

Answers (3)

sourcedelica
sourcedelica

Reputation: 24040

How about passing a reference to the MasterOrchestrator or the ThreadWorker into the Runnable's constructor? Then you can put all the configuration into the @Component class.

For example:

 private class ActualWorker implements Runnable{
      private int numRun;
      private ActualWorker(ThreadWorkerI owner, int numRun){
          this.numRun = numRun;
      }
      public void run(){
          //send message using owner.jmsTemplate, owner.dataObj and numRun
      }
  }

Upvotes: 0

Biju Kunjummen
Biju Kunjummen

Reputation: 49915

You can use @Configurable annotation to let Spring inject dependencies into your workers - even the one's that are not managed explicitly by the Spring container.

Upvotes: 1

Eugene Kuleshov
Eugene Kuleshov

Reputation: 31795

Instead of starting your own threads it is better to use thread pool or Spring's task executor abstraction. Then your tasks can be Spring beans or manually instantiated.

Upvotes: 0

Related Questions