2017-09-20 1 views
0

Je suis nouveau à Spring et j'essaie d'implémenter un programme multi-thread. Selon la documentation de printemps dans ce lien, https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html, fils peuvent être créés comme,Création de threads avec Spring

public class TaskExecutorExample { 
    private class MessagePrinterTask implements Runnable { 
    private String message; 
    public MessagePrinterTask(String message) { 
     this.message = message; 
    } 
    public void run() { 
     System.out.println(message); 
    } 
    } 

    private TaskExecutor taskExecutor; 
    public TaskExecutorExample(TaskExecutor taskExecutor) { 
    this.taskExecutor = taskExecutor; 
    } 
    public void printMessages() { 
    for(int i = 0; i < 25; i++) { 
     taskExecutor.execute(new MessagePrinterTask("Message" + i)); 
    } 
    } 
} 

Mais le fil de discussion est créé avec un « nouveau » mot-clé et le haricot est pas géré par Spring. Par conséquent, il ne peut accéder à aucun composant Autowired. Un travail autour de ce problème peut être Autowire le composant dans la classe outside et le passer à la classe thread dans son constructeur.

Mais existe-t-il un autre moyen approprié de faire cela, où Spring peut prendre soin d'initialiser les threads, afin que les threads puissent avoir accès à tous les composants câblés automatiquement.

L'application que je crée devra créer un nouveau thread pour chaque nouveau message qu'elle reçoit d'une file d'attente.

Répondre

1

Je suppose que les questions sont sur la façon d'initier le TaskExecutor et de l'utiliser ?! Ainsi, les documents montrent la façon de le faire:

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 
    <property name="corePoolSize" value="5" /> 
    <property name="maxPoolSize" value="10" /> 
    <property name="queueCapacity" value="25" /> 
</bean> 

<bean id="taskExecutorExample" class="TaskExecutorExample"> 
    <constructor-arg ref="taskExecutor" /> 
</bean> 

Ou vous pouvez faire dans votre code à l'aide @Bean comme

@Bean 
    public ThreadPoolTaskExecutor threadPool() { 
     ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor(); 
     pool.setCorePoolSize(5); 
     pool.setMaxPoolSize(10); 
     pool.setQueueCapacity(25); 
     return pool; 
    } 

    @Bean 
    public TaskExecutorExample executorExample() { 
    return new TaskExecutorExample(threadPool()); 
    } 

Ensuite, vous pouvez @Autowired l'utiliser. A propos des détails de corePoolSize, maxPoolSize, queueCapacity, vous pouvez consulter ici: http://www.bigsoft.co.uk/blog/index.php/2009/11/27/rules-of-a-threadpoolexecutor-pool-size

EDIT1: après avoir la clarification de Samo, je voudrais le mettre à jour:

Ajouter à votre @component Thread avec le @Scope ("prototype"). Ensuite, utilisez @Autowired votre fil et exécuter taskExecutor.execute (sampleThread)

Exemple ici: https://www.mkyong.com/spring/spring-and-java-thread-example/ Partie: 3. Discussion de printemps Piscine + gérés par Spring exemple haricot

Hope cette aide.

+0

Salut. Ma question était sur la façon de créer un fil lors de la soumission au pool de threads. Si vous utilisez 'new Thread()' pour en créer un, puis le soumettre au pool de threads, Spring ne gère pas l'objet thread que nous avons créé. Alors comment créer une instance de thread pour qu'elle soit gérée au printemps. – samo

+0

Ajoutez juste '@ Component' à votre Thread avec' @Scope ("prototype") '. Ensuite vous pouvez '@ Autowired' votre Thread et exécuter' taskExecutor.execute (sampleThread) 'comme ça. –

+0

@samo: juste au cas où vous auriez encore besoin de renvoyer l'échantillon. Pls voir 3. Spring Thread Pool + Spring exemple de haricot géré: https://www.mkyong.com/spring/spring-and-java-thread-example/ –