 |
 |
14) Les Threads multiples |
|
 |
|
Texte original |
 |
Traducteur : Cédric BABAULT |
|
 |
|
 |
 |
 |
 |
 |
 |
|
 |
|
 |
 |
 |
Priorities
|
 |
Priorités
|
 |
 |
 |
The
priority of a thread
tells the scheduler how important this thread is. If there are a number of
threads blocked and waiting to be run, the scheduler will run the one with the
highest priority first. However, this doesn’t mean that threads with lower
priority don’t get run (that is, you can’t get deadlocked because of
priorities). Lower priority threads just tend to run less
often.
|
 |
La priorité d'un thread dit à l'ordonnanceur
[scheduler] l'importance de ce thread. Si il y a un certain nombre de threads bloqués
et en attente d'exécution, l'ordonnanceur exécutera celui avec la plus haute
priorité en premier. Cependant, cela ne signifie pas que les threads avec des
priorités plus faibles ne tourneront pas (en fait, vous ne pouvez pas avoir d'interblocage
à cause des priorités). Les threads de priorités plus faibles ont juste
tendance à tourner moins souvent.
|
 |
 |
 |
Although priorities are interesting to
know about and to play with, in practice you almost never need to set priorities
yourself. So feel free to skip the rest of this section if priorities
aren’t interesting to you.
|
 |
Bien qu'il soit intéressant de connaître et de jouer avec les
priorités, en pratique vous n'avez pratiquement jamais besoin de gérer les
priorités par vous même. Donc soyez libre de passer le reste de cette session si les
priorités ne vous intéressent pas.
|
 |
 |
 |
Reading and setting priorities
|
 |
Lire et changer les priorités
|
 |
 |
 |
You can read the priority of a thread
with getPriority( )
and change it with
setPriority( ). The
form of the prior “counter” examples can be used to show the effect
of changing the priorities. In this applet you’ll see that the counters
slow down as the associated threads have their priorities
lowered:
|
 |
Vous pouvez lire la priorité d'un thread avec getPriority()
et la changer avec setPriority(). La forme des précédents exemples
« counter » peut être utiliser pour montrer l'effet des changements de
priorités. Dans cette applet vous verrez que les compteurs ralentissent quand les threads
associés ont leurs priorités diminuées:
|
 |
 |
 |
//: c14:Counter5.java // Adjusting the priorities of threads. // <applet code=Counter5 width=450 height=600> // </applet> import javax.swing.*; import java.awt.*; import java.awt.event.*; import com.bruceeckel.swing.*;
class Ticker2 extends Thread { private JButton b = new JButton("Toggle"), incPriority = new JButton("up"), decPriority = new JButton("down"); private JTextField t = new JTextField(10), pr = new JTextField(3); // Display priority private int count = 0; private boolean runFlag = true; public Ticker2(Container c) { b.addActionListener(new ToggleL()); incPriority.addActionListener(new UpL()); decPriority.addActionListener(new DownL()); JPanel p = new JPanel(); p.add(t); p.add(pr); p.add(b); p.add(incPriority); p.add(decPriority); c.add(p); } class ToggleL implements ActionListener { public void actionPerformed(ActionEvent e) { runFlag = !runFlag; } } class UpL implements ActionListener { public void actionPerformed(ActionEvent e) { int newPriority = getPriority() + 1; if(newPriority > Thread.MAX_PRIORITY) newPriority = Thread.MAX_PRIORITY; setPriority(newPriority); } } class DownL implements ActionListener { public void actionPerformed(ActionEvent e) { int newPriority = getPriority() - 1; if(newPriority < Thread.MIN_PRIORITY) newPriority = Thread.MIN_PRIORITY; setPriority(newPriority); } } public void run() { while (true) { if(runFlag) { t.setText(Integer.toString(count++)); pr.setText( Integer.toString(getPriority())); } yield(); } } }
public class Counter5 extends JApplet { private JButton start = new JButton("Start"), upMax = new JButton("Inc Max Priority"), downMax = new JButton("Dec Max Priority"); private boolean started = false; private static final int SIZE = 10; private Ticker2[] s = new Ticker2[SIZE]; private JTextField mp = new JTextField(3); public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); for(int i = 0; i < s.length; i++) s[i] = new Ticker2(cp); cp.add(new JLabel( "MAX_PRIORITY = " + Thread.MAX_PRIORITY)); cp.add(new JLabel("MIN_PRIORITY = " + Thread.MIN_PRIORITY)); cp.add(new JLabel("Group Max Priority = ")); cp.add(mp); cp.add(start); cp.add(upMax); cp.add(downMax); start.addActionListener(new StartL()); upMax.addActionListener(new UpMaxL()); downMax.addActionListener(new DownMaxL()); showMaxPriority(); // Recursively display parent thread groups: ThreadGroup parent = s[0].getThreadGroup().getParent(); while(parent != null) { cp.add(new Label( "Parent threadgroup max priority = " + parent.getMaxPriority())); parent = parent.getParent(); } } public void showMaxPriority() { mp.setText(Integer.toString( s[0].getThreadGroup().getMaxPriority())); } class StartL implements ActionListener { public void actionPerformed(ActionEvent e) { if(!started) { started = true; for(int i = 0; i < s.length; i++) s[i].start(); } } } class UpMaxL implements ActionListener { public void actionPerformed(ActionEvent e) { int maxp = s[0].getThreadGroup().getMaxPriority(); if(++maxp > Thread.MAX_PRIORITY) maxp = Thread.MAX_PRIORITY; s[0].getThreadGroup().setMaxPriority(maxp); showMaxPriority(); } } class DownMaxL implements ActionListener { public void actionPerformed(ActionEvent e) { int maxp = s[0].getThreadGroup().getMaxPriority(); if(--maxp < Thread.MIN_PRIORITY) maxp = Thread.MIN_PRIORITY; s[0].getThreadGroup().setMaxPriority(maxp); showMaxPriority(); } } public static void main(String[] args) { Console.run(new Counter5(), 450, 600); } } ///:~
|
 |
//: c14:Counter5.java // Ajuster les priorités des threads. // <applet code=Counter5 width=450 height=600> // </applet> import javax.swing.*; import java.awt.*; import java.awt.event.*; import com.bruceeckel.swing.*;
class Ticker2 extends Thread { private JButton b = new JButton("Toggle"), incPriority = new JButton("up"), decPriority = new JButton("down"); private JTextField t = new JTextField(10), pr = new JTextField(3); // Affiche la priorité private int count = 0; private boolean runFlag = true; public Ticker2(Container c) { b.addActionListener(new ToggleL()); incPriority.addActionListener(new UpL()); decPriority.addActionListener(new DownL()); JPanel p = new JPanel(); p.add(t); p.add(pr); p.add(b); p.add(incPriority); p.add(decPriority); c.add(p); } class ToggleL implements ActionListener { public void actionPerformed(ActionEvent e) { runFlag = !runFlag; } } class UpL implements ActionListener { public void actionPerformed(ActionEvent e) { int newPriority = getPriority() + 1; if(newPriority > Thread.MAX_PRIORITY) newPriority = Thread.MAX_PRIORITY; setPriority(newPriority); } } class DownL implements ActionListener { public void actionPerformed(ActionEvent e) { int newPriority = getPriority() - 1; if(newPriority < Thread.MIN_PRIORITY) newPriority = Thread.MIN_PRIORITY; setPriority(newPriority); } } public void run() { while (true) { if(runFlag) { t.setText(Integer.toString(count++)); pr.setText( Integer.toString(getPriority())); } yield(); } } }
public class Counter5 extends JApplet { private JButton start = new JButton("Start"), upMax = new JButton("#004488">"Inc Max Priority"), downMax = new JButton("#004488">"Dec Max Priority"); private boolean started = false; private static final int SIZE = 10; private Ticker2[] s = new Ticker2[SIZE]; private JTextField mp = new JTextField(3); public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); for(int i = 0; i < s.length; i++) s[i] = new Ticker2(cp); cp.add(new JLabel( "MAX_PRIORITY = " + Thread.MAX_PRIORITY)); cp.add(new JLabel("MIN_PRIORITY = " + Thread.MIN_PRIORITY)); cp.add(new JLabel("#004488">"Group Max Priority = ")); cp.add(mp); cp.add(start); cp.add(upMax); cp.add(downMax); start.addActionListener(new StartL()); upMax.addActionListener(new UpMaxL()); downMax.addActionListener(new DownMaxL()); showMaxPriority(); // Affiche récursivement les groupes de thread parents: ThreadGroup parent = s[0].getThreadGroup().getParent(); while(parent != null) { cp.add(new Label( "Parent threadgroup max priority = " + parent.getMaxPriority())); parent = parent.getParent(); } } public void showMaxPriority() { mp.setText(Integer.toString( s[0].getThreadGroup().getMaxPriority())); } class StartL implements ActionListener { public void actionPerformed(ActionEvent e) { if(!started) { started = true; for(int i = 0; i < s.length; i++) s[i].start(); } } } class UpMaxL implements ActionListener { public void actionPerformed(ActionEvent e) { int maxp = s[0].getThreadGroup().getMaxPriority(); if(++maxp > Thread.MAX_PRIORITY) maxp = Thread.MAX_PRIORITY; s[0].getThreadGroup().setMaxPriority(maxp); showMaxPriority(); } } class DownMaxL implements ActionListener { public void actionPerformed(ActionEvent e) { int maxp = s[0].getThreadGroup().getMaxPriority(); if(--maxp < Thread.MIN_PRIORITY) maxp = Thread.MIN_PRIORITY; s[0].getThreadGroup().setMaxPriority(maxp); showMaxPriority(); } } public static void main(String[] args) { Console.run(new Counter5(), 450, 600); } } ///:~
|
 |
 |
 |
Ticker2 follows the form
established earlier in this chapter, but there’s an extra
JTextField for displaying the priority of the thread and two more buttons
for incrementing and decrementing the priority.
|
 |
Ticker2 suit la forme établie plus tôt dans ce
chapitre, mais il y a un JTextField supplémentaire pour afficher la priorité
du thread et deux bouttons de plus pour incrémenter et décrémenter la
priorité.
|
 |
 |
 |
Also notice the use of
yield( ), which voluntarily hands control back to the scheduler.
Without this the multithreading mechanism still works, but you’ll notice
it runs slowly (try removing the call to yield( ) to see this). You
could also call sleep( ), but then the rate of counting would be
controlled by the sleep( ) duration instead of the
priority.
|
 |
Vous pouvez également noter l'utilisation de yield(), qui
rend volontairement la main à l'ordonnanceur. Sans cela le mécanisme de
multithreading fonctionne encore, mais vous remarquerez qu'il tourne plus lentement (essayez de
supprimer l'appel à yield() pour le voir). Vous pouvez aussi appeler sleep(),
mais alors la vitesse de comptage sera controller par la durée du sleep() au lieu de
la priorité.
|
 |
 |
 |
The init( ) in
Counter5 creates an array of ten Ticker2s; their buttons and
fields are placed on the form by the Ticker2 constructor. Counter5
adds buttons to start everything up as well as increment and decrement the
maximum priority of the thread group. In addition, there are labels that display
the maximum and minimum priorities possible for a thread and a JTextField
to show the thread group’s maximum priority. (The next section will
describe thread groups.) Finally, the priorities of the parent thread groups are
also displayed as labels.
|
 |
Le init() dans Counter5 crée un tableau de dix
Ticker2s; leurs bouttons et champs sont placés sur le formulaire par le constructeur
de Ticker2. Counter5 ajoute des bouttons pour tout démarrer aussi bien que
pour incrémenter et décrémenter la priorité maximum du groupe de
thread. En plus, il y a des labels qui affichent les priorités maximum et minimum possibles
pour un thread et un JTextField pour montrer la priorité maximum du groupe de thread.
(La prochaine section décrira les groupes de threads.) Finalement, les priorités des
groupes de threads parents sont aussi afficher comme labels.
|
 |
 |
 |
When you press an “up” or
“down” button, that Ticker2’s priority is fetched and
incremented or decremented accordingly.
|
 |
Quand vous pressez un bouton « up » ou
« down », la priorité du Tricker2 est rapportée et
incrémenter ou décrémenter en conséquence.
|
 |
 |
 |
When you run this program, you’ll
notice several things. First of all, the thread group’s
default priority is five. Even
if you decrement the maximum priority below five before starting the threads (or
before creating the threads, which requires a code change), each thread will
have a default priority of five.
|
 |
Quand vous exécutez ce programme, vous noterez plusieurs choses.
Tout d'abord, la priorité du groupe de thread est par défaut cinq. Même si vous
décrémentez la priorité maximum en dessous de cinq avant de démarrer
les threads (ou avant de les créer, ce qui nécessite un changement du code), chaque
thread aura une priorité par défaut de cinq.
|
 |
 |
 |
The simple test is to take one counter
and decrement its priority to one, and observe that it counts much slower. But
now try to increment it again. You can get it back up to the thread
group’s priority, but no higher. Now decrement the thread group’s
priority a couple of times. The thread priorities are unchanged, but if you try
to modify them either up or down you’ll see that they’ll
automatically pop to the priority of the thread group. Also, new threads will
still be given a default priority, even if that’s higher than the group
priority. (Thus the group priority is not a way to prevent new threads from
having higher priorities than existing ones.)
|
 |
Le test simple est de prendre un compteur et de décrémenter
sa priorité jusqu'à un, et observez qu'il compte beaucoup plus lentement. Mais
maintenant essayez de l'incrémenter de nouveau. Vous pouvez le ramené à la
priorité du groupe de thread, mais pas plus haut. Maintenant décrémentez la
priorité du groupe de threads. Les priorités des threads restent inchangées,
mais si vous essayez de les modifier dans un sens ou dans l'autre vous verrez qu'elles sauteront
automatiquement à la priorité du groupe de thread. Les nouvelles threads auront
également une priorité par défaut qui peut être plus haute que la
priorité du groupe. (Ainsi la priorité du groupe n'est pas un moyen d'empêcher
les nouveaux threads d'avoir des priorités plus hautes que celles existantes.)
|
 |
 |
 |
Finally, try to increment the group
maximum priority. It can’t be done. You can only reduce thread group
maximum priorities, not increase
them.
|
 |
Finalement, essayez d'incrémenter la priorité maximum du
groupe. On ne peut pas le faire. Vous pouvez seulement réduire la priorité maximum
d'un groupe de thread, pas l'augmenter.
|
 |
 |
 |
Thread groups
|
 |
Les groupes de threads
|
 |
 |
 |
All threads belong to a
thread group. This can be either the default thread
group or a group you explicitly specify when you create the thread. At creation,
the thread is bound to a group and cannot change to a different group. Each
application has at least one thread that belongs to the system thread group. If
you create more threads without specifying a group, they will also belong to the
system thread group.
|
 |
Tous les threads appartiennent à un groupe de thread. Ce peut
être soit le groupe de thread par défaut, soit un groupe de thread que vous
spécifiez explicitement quand vous créez le thread. A la création, le thread
est attaché à un groupe et ne peut pas en changer. Chaque application a au moins un
thread qui appartient au groupe de thread système. Si vous créez plus de threads sans
spécifier de groupe, ils appartiendront aussi au groupe de thread système.
|
 |
 |
 |
Thread groups must also belong to other
thread groups. The thread group that a new one belongs to must be specified in
the constructor. If you create a thread group without specifying a thread group
for it to belong to, it will be placed under the system thread group. Thus, all
thread groups in your application will ultimately have the system thread group
as the parent.
|
 |
Les groupes de threads doivent aussi appartenir à d'autres groupes
de threads. Le groupe de thread auquel un nouveau appartient doit être spécifié
dans le constructeur. Si vous créez un groupe de thread sans spécifier de groupe
auquel le rattacher, il sera placer dans le groupe de thread système. Ainsi, tous les
groupes de threads de votre application auront en fin de compte le groupe de thread système
comme parent.
|
 |
 |
 |
The reason for the existence of thread
groups is hard to determine from the literature, which tends to be confusing on
this subject. It’s often cited as “security reasons.”
According to Arnold &
Gosling,[71]
“Threads within a thread group can modify the other threads in the group,
including any farther down the hierarchy. A thread cannot modify threads outside
of its own group or contained groups.” It’s hard to know what
“modify” is supposed to mean here. The following example shows a
thread in a “leaf” subgroup modifying the priorities of all the
threads in its tree of thread groups as well as calling a method for all the
threads in its tree.
|
 |
La raison de l'existence des groupes de threads est difficile à
déterminer à partir de la littérature, qui tend à être confuse
sur le sujet. Il est souvent cité des raisons de sécurités. D'après
Arnold & Gosling,« Les threads d'un groupe peuvent modifier les autres threads du
groupe, y compris ceux situés plus bas dans la hiérarchie. Un thread ne peut pas
modifier les threads extérieurs à son propre groupe ou les groupes qu'il
contient. » Il est difficile de savoir ce que « modifier » est
supposé signifier ici. L'exemple suivant montre un thread dans un sous-groupe
« feuille » modifier les priorités de tous les threads de son arbre de
groupe de thread aussi bien qu'appeler une méthode pour tous les threads de son
arbre.
|
 |
 |
 |
//: c14:TestAccess.java // How threads can access other threads // in a parent thread group.
public class TestAccess { public static void main(String[] args) { ThreadGroup x = new ThreadGroup("x"), y = new ThreadGroup(x, "y"), z = new ThreadGroup(y, "z"); Thread one = new TestThread1(x, "one"), two = new TestThread2(z, "two"); } }
class TestThread1 extends Thread { private int i; TestThread1(ThreadGroup g, String name) { super(g, name); } void f() { i++; // modify this thread System.out.println(getName() + " f()"); } }
class TestThread2 extends TestThread1 { TestThread2(ThreadGroup g, String name) { super(g, name); start(); } public void run() { ThreadGroup g = getThreadGroup().getParent().getParent(); g.list(); Thread[] gAll = new Thread[g.activeCount()]; g.enumerate(gAll); for(int i = 0; i < gAll.length; i++) { gAll[i].setPriority(Thread.MIN_PRIORITY); ((TestThread1)gAll[i]).f(); } g.list(); } } ///:~
|
 |
//: c14:TestAccess.java // Comment les threads peuvent accéder aux // autres threads dans un groupe de threads parent.
public class TestAccess { public static void main(String[] args) { ThreadGroup x = new ThreadGroup("x"), y = new ThreadGroup(x, "y"), z = new ThreadGroup(y, "z"); Thread one = new TestThread1(x, "one"), two = new TestThread2(z, "two"); } }
class TestThread1 extends Thread { private int i; TestThread1(ThreadGroup g, String name) { super(g, name); } void f() { i++; // modifie ce thread System.out.println(getName() + " f()"); } }
class TestThread2 extends TestThread1 { TestThread2(ThreadGroup g, String name) { super(g, name); start(); } public void run() { ThreadGroup g = getThreadGroup().getParent().getParent(); g.list(); Thread[] gAll = new Thread[g.activeCount()]; g.enumerate(gAll); for(int i = 0; i < gAll.length; i++) { gAll[i].setPriority(Thread.MIN_PRIORITY); ((TestThread1)gAll[i]).f(); } g.list(); } } ///:~
|
 |
 |
 |
In main( ), several
ThreadGroups are created, leafing off from each other: x has no
argument but its name (a String), so it is automatically placed in the
“system” thread group, while y is under x and z
is under y. Note that initialization happens in textual order so this
code is legal.
|
 |
Dans main(), plusieurs ThreadGroups sont créés,
placés en feuilles des autres: x n'a pas d'autres arguments que son nom (une
String), ainsi il est automatiquement placé dans le groupe de threads
« système », tandis que y est sous x et z est
sous y. Notez que l'initialisation se passe dans l'ordre textuel donc ce code est
légal.
|
 |
 |
 |
Two threads are created and placed in
different thread groups. TestThread1 doesn’t have a
run( ) method but it does have an f( ) that modifies the
thread and prints something so you can see it was called. TestThread2 is
a subclass of TestThread1 and its run( ) is fairly elaborate.
It first gets the thread group of the current thread, then moves up the heritage
tree by two levels using getParent( ). (This is contrived since I
purposely place the TestThread2 object two levels down in the hierarchy.)
At this point, an array of references to Threads is created using the
method activeCount( ) to ask how many threads are in this thread
group and all the child thread groups. The enumerate( ) method
places references to all of these threads in the array gAll, then I
simply move through the entire array calling the f( ) method for
each thread, as well as modifying the priority. Thus, a thread in a
“leaf” thread group modifies threads in parent thread
groups.
|
 |
Deux threads sont créés et placés dans
différents groupes de threads. TestThread1 n'a pas de méthode run()
mais a une méthode f() qui modifie le thread et écrit quelque chose afin que
vous puissiez voir qu'elle a été appelée. TestThread2 est une sous
classe de TestThread1 et sa méthode run() est assez élaboré.
Elle récupère d'abord le groupe de thread du thread courant, puis remonte deux
niveaux dans l'arbre d'héritage en utilisant getParent(). (Ceci est
étudié puisque j'ai intentionnellement placer l'objet TestThread2 deux niveaux
plus bas dans la hiérarchie.) A ce point, un tableau de références sur
Thread est créé en utilisant la méthode activeCount() pour
demander combien de threads sont dans ce groupe de thread et tous les groupes fils. La
méthode enumerate() place les références à toutes ces threads
dans le tableau gAll, ensuite je me parcourt simplement dans la totalité du tableau
en appelant la méthode f() pour chaque thread, ainsi qu'en modifiant la
priorité. Ainsi, un thread dans un groupe de thread « feuille »
modifie les threads dans les groupes de threads parents.
|
 |
 |
 |
The debugging method list( )
prints all the information about a thread group to standard output and is
helpful when investigating thread group behavior. Here’s the output of the
program:
|
 |
La méthode de déboguage list() affiche toutes
l'information sur un groupe de thread sur la sortie standard ce qui aide beaucoup lorsqu'on examine
le comportement d'un groupe de threads. Voici la sortie du programme:
|
 |
 |
 |
java.lang.ThreadGroup[name=x,maxpri=10] Thread[one,5,x] java.lang.ThreadGroup[name=y,maxpri=10] java.lang.ThreadGroup[name=z,maxpri=10] Thread[two,5,z] one f() two f() java.lang.ThreadGroup[name=x,maxpri=10] Thread[one,1,x] java.lang.ThreadGroup[name=y,maxpri=10] java.lang.ThreadGroup[name=z,maxpri=10] Thread[two,1,z]
|
 |
java.lang.ThreadGroup[name=x,maxpri=10] Thread[one,5,x] java.lang.ThreadGroup[name=y,maxpri=10] java.lang.ThreadGroup[name=z,maxpri=10] Thread[two,5,z] one f() two f() java.lang.ThreadGroup[name=x,maxpri=10] Thread[one,1,x] java.lang.ThreadGroup[name=y,maxpri=10] java.lang.ThreadGroup[name=z,maxpri=10] Thread[two,1,z]
|
 |
 |
 |
Not only does list( ) print
the class name of ThreadGroup or Thread, but it also prints the
thread group name and its maximum priority. For threads, the thread name is
printed, followed by the thread priority and the group that it belongs to. Note
that list( ) indents the threads and thread groups to indicate that
they are children of the unindented thread group.
|
 |
Non seulement list() affiche le nom du ThreadGroup ou du
Thread, mais elle affiche aussi le nom du groupe de thread et sa priorité maximum.
Pour les threads, le nom de thread est également affiché, suivi par la
priorité du thread et le groupe auquel il appartient. Notez que list() indente les
threads et groupes de threads pour indiquer qu'ils sont enfant du groupe de threads non
indenté.
|
 |
 |
 |
You can see that f( ) is
called by the TestThread2 run( ) method, so it’s
obvious that all threads in a group are vulnerable. However, you can access only
the threads that branch off from your own system thread group tree, and
perhaps this is what is meant by “safety.” You cannot access anyone
else’s system thread group tree.
|
 |
Vous pouvez voir que f() est appelé par la méthode
run() de TestThread2, il est donc évident que tous les threads d'un groupe
sont vulnérables. Cependant, vous ne pouvez accéder seulement aux threads
embranchés sur votre propre arbre du groupe de thread système, et
peut-être que c'est ce que signifie « sûr. » Vous ne pouvez pas
accéder à l'arbre du groupe de thread système d'un autre.
|
 |
 |
 |
Controlling thread groups
|
 |
Controller les groupes de threads
|
 |
 |
 |
Putting aside the safety issue, one thing
thread groups seem to be useful for is control: you can perform certain
operations on an entire thread group with a single command. The following
example demonstrates this, and the restrictions on priorities within thread
groups. The commented numbers in parentheses provide a reference to compare to
the output.
|
 |
En dehors de l'aspect sécurité, une chose pour lesquelles les
groupes de threads semble être utiles est le controle: vous pouvez effectuer certaines
opérations sur un groupe de thread entier avec une seule commande. L'exemple suivant le
démontre, et les restrictions sur les priorités avec les groupes de threads. Les
numéros entre parenthèses donne une référence pour comparer la
sortie.
|
 |
 |
 |
//: c14:ThreadGroup1.java // How thread groups control priorities // of the threads inside them.
public class ThreadGroup1 { public static void main(String[] args) { // Get the system thread & print its Info: ThreadGroup sys = Thread.currentThread().getThreadGroup(); sys.list(); // (1) // Reduce the system thread group priority: sys.setMaxPriority(Thread.MAX_PRIORITY - 1); // Increase the main thread priority: Thread curr = Thread.currentThread(); curr.setPriority(curr.getPriority() + 1); sys.list(); // (2) // Attempt to set a new group to the max: ThreadGroup g1 = new ThreadGroup("g1"); g1.setMaxPriority(Thread.MAX_PRIORITY); // Attempt to set a new thread to the max: Thread t = new Thread(g1, "A"); t.setPriority(Thread.MAX_PRIORITY); g1.list(); // (3) // Reduce g1's max priority, then attempt // to increase it: g1.setMaxPriority(Thread.MAX_PRIORITY - 2); g1.setMaxPriority(Thread.MAX_PRIORITY); g1.list(); // (4) // Attempt to set a new thread to the max: t = new Thread(g1, "B"); t.setPriority(Thread.MAX_PRIORITY); g1.list(); // (5) // Lower the max priority below the default // thread priority: g1.setMaxPriority(Thread.MIN_PRIORITY + 2); // Look at a new thread's priority before // and after changing it: t = new Thread(g1, "C"); g1.list(); // (6) t.setPriority(t.getPriority() -1); g1.list(); // (7) // Make g2 a child Threadgroup of g1 and // try to increase its priority: ThreadGroup g2 = new ThreadGroup(g1, "g2"); g2.list(); // (8) g2.setMaxPriority(Thread.MAX_PRIORITY); g2.list(); // (9) // Add a bunch of new threads to g2: for (int i = 0; i < 5; i++) new Thread(g2, Integer.toString(i)); // Show information about all threadgroups // and threads: sys.list(); // (10) System.out.println("Starting all threads:"); Thread[] all = new Thread[sys.activeCount()]; sys.enumerate(all); for(int i = 0; i < all.length; i++) if(!all[i].isAlive()) all[i].start(); // Suspends & Stops all threads in // this group and its subgroups: System.out.println("All threads started"); sys.suspend(); // Deprecated in Java 2 // Never gets here... System.out.println("All threads suspended"); sys.stop(); // Deprecated in Java 2 System.out.println("All threads stopped"); } } ///:~
|
 |
//: c14:ThreadGroup1.java // Comment les groupes de threads contrôlent les priorités // des threads qui les composent.
public class ThreadGroup1 { public static void main(String[] args) { // Récupère le thread system & imprime ses Info: ThreadGroup sys = Thread.currentThread().getThreadGroup(); sys.list(); // (1) // Réduit la priorité du groupe de thread système: sys.setMaxPriority(Thread.MAX_PRIORITY - 1); // Augmente la priorité du thread principal: Thread curr = Thread.currentThread(); curr.setPriority(curr.getPriority() + 1); sys.list(); // (2) // Essaie de créer un nouveau groupe avec une priorité maximum: ThreadGroup g1 = new ThreadGroup("#004488">"g1"); g1.setMaxPriority(Thread.MAX_PRIORITY); // Essaie de créer un nouveau thread avec une priorité maximum: Thread t = new Thread(g1, "A"); t.setPriority(Thread.MAX_PRIORITY); g1.list(); // (3) // Reduit la priorité maximum de g1, puis essaie // de l'augmenter: g1.setMaxPriority(Thread.MAX_PRIORITY - 2); g1.setMaxPriority(Thread.MAX_PRIORITY); g1.list(); // (4) // Essaie de créer un nouveau thread avec une priorité maximum: t = new Thread(g1, "B"); t.setPriority(Thread.MAX_PRIORITY); g1.list(); // (5) // Diminue la priorité maximum en dessous // de la priorité par défaut du thread: g1.setMaxPriority(Thread.MIN_PRIORITY + 2); // Regarde la priorité d'un nouveau thread // avant et après son changement: t = new Thread(g1, "C"); g1.list(); // (6) t.setPriority(t.getPriority() -1); g1.list(); // (7) // Fait de g2 un groupe de thread fils de g1 et // essaie d'augmenter sa priorité: ThreadGroup g2 = new ThreadGroup(g1, "#004488">"g2"); g2.list(); // (8) g2.setMaxPriority(Thread.MAX_PRIORITY); g2.list(); // (9) // Ajoute un banc de nouveaux threads à g2: for (int i = 0; i < 5; i++) new Thread(g2, Integer.toString(i)); // Montre des informations sur tous les groupes de threads // et threads: sys.list(); // (10) System.out.println("Starting all threads:"); Thread[] all = new Thread[sys.activeCount()]; sys.enumerate(all); for(int i = 0; i < all.length; i++) if(!all[i].isAlive()) all[i].start(); // Suspends & Arrête tous les threads de // ce groupe et de ses sous-groupes: System.out.println("All threads started"); sys.suspend(); // Deprecié en Java 2 // On n'arrive jamais ici... System.out.println("All threads suspended"); sys.stop(); // Deprecié en Java 2 System.out.println("All threads stopped"); } } ///:~
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |