5 votes

Passer les priorités des threads aux pools de threads

J'ai un composant Java qui exécute une logique commerciale super compliquée, dont une partie est parallélisée et les threads exécutant les sous-tâches sont mis en commun. Maintenant, chaque demande à ce composant peut avoir une certaine priorité qui est mise en correspondance d'une certaine manière avec la priorité du thread. Au début de l'exécution, je peux attribuer une priorité appropriée au thread qui s'exécute. La partie problématique est de passer la priorité à chaque thread exécutant des sous-tâches. Je sais que la création d'un nouveau thread enfant permettra d'y parvenir car les threads enfants héritent de la priorité des threads parents, mais j'aimerais tirer parti de la mise en commun des threads. Voici la question :

  • Existe-t-il un moyen de s'assurer que chaque thread dans le chemin d'exécution a la priorité appropriée ?
  • Comment puis-je surveiller la priorité des threads à chaque étape de l'exécution, bien sûr je ne veux pas coder en dur un code de traçage ? Une chose qui m'est venue à l'esprit est d'écrire un script de traçage en BTrace

Santé. Tomek

4voto

StaxMan Points 34626

Je suppose que vous le savez déjà, mais l'importance ou non de la valeur de priorité de Thread du JDK est très spécifique au système d'exploitation, et peut se traduire par "n'a aucun effet". Donc vous êtes sûr que ça compte vraiment ? Si c'est le cas, vous pouvez modifier la question pour mentionner le système d'exploitation sur lequel le système fonctionne.

De plus, il n'est pas très courant d'essayer d'utiliser les priorités de threads ; en plus des priorités qui ne fonctionnent pas nécessairement, il n'est pas trivial d'en faire bon usage même si elles fonctionnent. On utilise plus souvent des primitives de synchronisation, ainsi que le contrôle du niveau de concurrence (nombre de threads actifs), et non des priorités. Ceci parce qu'il y a rarement des avantages à avoir plus de threads actifs que de cœurs dont dispose le système.

4voto

Nick Wiggill Points 1914

Vous voulez utiliser des pools de threads, qui seraient rendus inutiles si vous deviez créer de nouveaux threads juste pour définir la priorité des tâches.

Je pense que vous voulez que chaque emploi (pas filetage ) pour avoir une priorité différente. Si c'est le cas, examinons la signature d'un constructeur de ThreadPoolExecutor :

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue)
  • Au lieu d'utiliser l'une des méthodes recommandées Executors pour construire votre pool de threads, procédez comme suit new ThreadPoolExecutor(...) vous-même, en utilisant l'une de ses nombreuses signatures.
  • Passez Executors.defaultThreadFactory dans ce constructeur (la signature que j'ai listée ci-dessus le fait en interne). Cela fera automatiquement filetage l'attribution de priorité lors de la création des threads (pour un pool de threads de taille fixe, cela ne devrait se produire qu'une fois par thread, au démarrage de l'application).
  • Passez un BlockingQueue<Runnable> o PriorityBlockingQueue<Runnable> dans ce constructeur. Il s'agit de la file d'attente qui vous permettra d'établir des priorités dans les cas suivants emplois (pas fils ).
  • Étendre le site Runnable en un résumé PriorityRunnable classe qui permet d'obtenir/de fixer la priorité. Ceux-ci représentent les emplois Ainsi, lorsque vous souhaitez créer une nouvelle tâche, il vous suffit de l'étendre et de définir la priorité en fonction de cette tâche.
  • Mettre en œuvre Comparator pour effectuer le classement des éléments au fur et à mesure que vous les insérez dans la file d'attente, et laissez cette file l'utiliser.
  • Ajoutez vos travaux à la file d'attente.

Notez que si votre file d'attente est déjà remplie à ce moment-là (par exemple, pour les applications de traitement par lots), vous pouvez appeler la fonction executor.prestartAllCoreThreads() o executor.prestartCoreThread(n) immédiatement après la construction.

Tout cela est assez simple et ne nécessite que quelques lignes de code pour être mis en place.

EDIT : Je viens de trouver la même approche en cours de discussion. sur le site de Java Ranch .

3voto

Sanjay T. Sharma Points 12620

En ce qui concerne le réglage de la priorité du thread, vous pouvez utiliser les différentes méthodes de la fonction Exécuteurs testamentaires qui prend une ThreadFactory. Cette fabrique sera responsable de la création de threads basés sur le "Runnable" transmis.

En ce qui concerne le suivi, pouvez-vous extrapoler sur le scénario que vous essayez d'aborder ici lorsque vous dites "chaque étape de l'exécution" ? Comme il a été mentionné Par ailleurs, étant donné qu'il n'existe pas de correspondance claire entre les priorités des threads de Java et du système d'exploitation, s'appuyer sur ces priorités serait une mauvaise chose, au cas où c'est ce que vous essayez de faire ici.

2voto

giuppo73 Points 11

Ceci pourrait résoudre votre problème : Thread.currentThread().setPriority([1..5]) ;

Vous pouvez les utiliser de n'importe où. Si vous les utilisez à l'intérieur d'un runnable lancé par un pool de threads, vous pouvez contrôler la priorité du single thread et la modifier si nécessaire.

2voto

Leon Barrett Points 111

Je l'ai récemment mis en œuvre. Je l'ai fait à peu près comme Nick Wiggill l'a suggéré.

Mais vous ne pouvez pas simplement faire ce qu'il a suggéré, parce que ThreadPoolExecutor ne met pas les tâches que vous avez demandées dans la file d'attente des travaux - au lieu de cela, il les enveloppe dans son propre RunnableFuture et les met dans la file d'attente. Vous devez donc surcharger sa méthode newTaskFor pour lui transmettre la priorité.

Le code source est en ligne sous la licence Apache 2.0 : https://github.com/TheClimateCorporation/claypoole/blob/master/src/java/com/climate/claypoole/impl/PriorityThreadpoolImpl.java

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X