Vous pouvez exécuter des opérations en parallèle en encapsulant le code dans une tâche appelable ou exécutable et en soumettant ou en planifiant son exécution auprès d'un programme d'exécution.
Avant de commencer
Le cas échéant, votre administrateur peut utiliser la console d'administration pour configurer au moins un gestionnaire de travaux ou modifier les paramètres du gestionnaire de travaux par défaut.
A propos de cette tâche
Pour exécuter le code en parallèle, encapsulez-le dans une tâche appelable ou exécutable et soumettez ou planifiez son exécution auprès d'un programme d'exécution géré.
Procédure
- Implémentez une tâche appelable ou exécutable.
Une tâche implémente l'interface java.util.concurrent.Callable ou java.lang.Runnable. Par exemple, vous pouvez créer une tâche qui permet de s'abonner de manière dynamique à une rubrique et à n'importe quel composant.
class SampleTask implements Callable<Object>
{
Set<MessageListener> listeners =
Collections.newSetFromMap(new ConcurrentHashMap<MessageListener, Boolean>();
Topic targetTopic;
TopicConnectionFactory tcf;
public SampleWork(TopicConnectionFactory tcf, Topic targetTopic)
{
this.targetTopic = targetTopic;
this.tcf = tcf;
}
public void addMessageListener(MessageListener listener)
{
listeners.add(listener);
}
public Object call() throws JMSException
{
// setup our JMS stuff.TopicConnection
tc = tcf.createConnection();
try
{
TopicSession sess = tc.createSession(false, Session.AUTOACK);
tc.start();
while( !Thread.currentThread().isInterrupted() )
{
// block for up to 5 seconds.
Message msg = sess.receiveMessage(5000);
if( msg != null )
for (MessageListener listener : listeners)
listener.onMessage(msg);
}
tc.close();
}
finally
{
if (tc != null) tc.close();
}
return null;
}
}
Par conséquent, tout composant peut ajouter un programme d'écoute de message à la demande, ce qui permet aux composants de s'abonner à une rubrique. Ce mécanisme est plus souple que l'attribution de sa propre unité d'exécution à chaque abonné client.
- Déterminez le nombre de gestionnaires de travaux requis
par ce composant d'application.
- Recherchez le ou les gestionnaires de travaux à l'aide du programme d'exécution géré, de la fabrique d'unités d'exécution, de la référence d'environnement de ressource de service de contexte ou de la référence de ressource de gestionnaire de travaux (ou nom logique) dans l'espace de nom
java:comp . (Pour plus d'informations sur les références d'environnement de ressource et sur les références de ressource, voir la rubrique Références).
InitialContext ic = new InitialContext();
ManagedExecutorService executor = (ManagedExecutorService)ic.lookup("java:comp/env/concurrent/myWorkManager");
La référence d'environnement de ressource du programme d'exécution géré (dans notre
exemple, concurrent/myWorkManager) doit être déclarée en
tant que référence d'environnement de ressource dans le descripteur de déploiement d'application ou dans une annotation @Resource.
- Appelez la méthode
ManagedExecutorService.submit() en utilisant l'instance de tâche appelable ou exécutable comme paramètre.Par exemple :
Callable<Boolean> task = new MyTask(...);
Future<Boolean> future = executor.submit(task);
Future est un descripteur qui établit un lien entre le composant et la tâche soumise.
- Facultatif: Si votre composant d'application doit attendre la fin d'une ou de plusieurs de ses tâches, appelez la méthode
Future.get() .Par exemple :
Future<String> futureA = executor.submit(taskA);
Future<String> futureB = executor.submit(taskB);
futureA.get(5, TimeUnit.SECONDS);
futureB.get(5, TimeUnit.SECONDS);
Sinon, utilisez la méthode invokeAll() pour soumettre plusieurs tâches et attendez qu'elles soient toutes terminées. Par exemple :
tasks = Arrays.asList(taskA, taskB);
futures = executor.invokeAll(tasks, 5, TimeUnit.SECONDS);
// we can check future.isDone() to see which, if any, finished.
Cette méthode prend une collection de tâches pour laquelle le composant souhaite attendre la fin de l'exécution de tous les objets de travail. Vous pouvez également spécifier un délai d'attente.
- Utilisez la méthode
Future.cancel(true) pour tenter d'interrompre la tâche.
Implémentez la tâche dans le but de répondre immédiatement à l'interruption ou essayez d'arrêter l'exécution dès que possible.