Reputation: 5915
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
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
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
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