1
2
3
|
sleep(long millis) //参数为毫秒
sleep(long millis,int nanoseconds) //第一参数为毫秒,第二个参数为纳秒
|
123 |
sleep(long millis) //Le paramètre est millisecondes sleep(long millis,int nanoseconds) //Le premier paramètre est les millisecondes, le deuxième paramètre est les nanosecondes |
La veille équivaut à laisser le thread dormir, à remettre le processeur et à laisser le processeur effectuer d'autres tâches.
Mais une chose à noter est que la méthode sleep ne libérera pas le verrou, c'est-à-dire que si le thread actuel détient un verrou sur un objet, les autres threads ne pourront pas accéder à l'objet même si. la méthode sleep est appelée. Cela deviendra clair lorsque vous regarderez l'exemple suivant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
public class Test {
private int i = 10;
private Object object = new Object();
public static void main(String[] args) throws IOException {
Test test = new Test();
MyThread thread1 = test.new MyThread();
MyThread thread2 = test.new MyThread();
thread1.start();
thread2.start();
}
class MyThread extends Thread{
@Override
public void run() {
synchronized (object) {
i++;
System.out.println("i:"+i);
try {
System.out.println("线程"+Thread.currentThread().getName()+"进入睡眠状态");
Thread.currentThread().sleep(10000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println("线程"+Thread.currentThread().getName()+"睡眠结束");
i++;
System.out.println("i:"+i);
}
}
}
}
|
123456789101112131415 16 1718192021222324252627282930313233 |
Test en classe publique { private int i = 10; private Object object = new Object(); public static void main(String[] args) lance IOException { Test test = new Test(); MyThread thread1 = test.new MyThread(); MyThread thread2 = test.new MyThread(); thread1.start( ); thread2.start(); } @Override public void run() { synchronisé (objet) { i++; System.out .println("i:"+ i); essayez { System. out.println("Thread"+Thread.currentThread().getName()+"Enter sleep state"); Thread.currentThread().sleep(10000); } catch (InterruptedException e) { } Système .out.println("Thread"+Thread.currentThread().getName()+"Sleep End"); i++; System.out.println("i:"+ i); } } }} |
Résultats de sortie :
N'a pas effectué de tâches spécifiques. Ce n'est que lorsque Thread-0 termine l'exécution et que Thread-0 libère le verrou d'objet que Thread-1 commence l'exécution.
Notez que si la méthode sleep est appelée, l'InterruptedException doit être interceptée ou lancée vers la couche supérieure. Lorsque le temps de veille du thread est écoulé, il peut ne pas être exécuté immédiatement car le processeur peut effectuer d'autres tâches à ce moment-là. Donc appeler la méthode sleep équivaut à mettre le thread dans un état bloquant.
4) Méthode Yield L'appel de la méthode Yield entraînera le thread actuel à céder les autorisations du processeur et à laisser le processeur exécuter d'autres threads. Elle est similaire à la méthode sleep et ne libère pas le verrou. Cependant, Yield ne peut pas contrôler l'heure spécifique de transfert du CPU. De plus, la méthode Yield ne peut permettre qu'aux threads ayant la même priorité d'avoir la possibilité d'obtenir le temps d'exécution du CPU. Notez que l'appel de la méthode rendement ne met pas le thread dans l'état de blocage, mais ramène le thread à l'état prêt. Il suffit d'attendre que le temps d'exécution du CPU soit réacquis, ce qui est différent du temps d'exécution du CPU. méthode de sommeil. 5) méthode join La méthode join a trois versions surchargées :
1
2
3
1
2
3
|
join()
join(long millis) //参数为毫秒
join(long millis,int nanoseconds) //第一参数为毫秒,第二个参数为纳秒
|
|
rejoindre()rejoindre(long millis) //Le paramètre est en millisecondesjoin(long millis,int nanoseconds) //Le premier paramètre est en millisecondes, le deuxième paramètre est en nanosecondes |
Si la méthode thread.join est appelée dans le thread principal, la méthode principale attendra que le thread du thread termine son exécution ou attendra un certain temps. Si la méthode de jointure sans paramètres est appelée, attendez que le thread termine son exécution. Si la méthode de jointure avec un paramètre de temps spécifié est appelée, attendez un certain événement.
Regardez l'exemple suivant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public class Test {
public static void main(String[] args) throws IOException {
System.out.println("进入线程"+Thread.currentThread().getName());
Test test = new Test();
MyThread thread1 = test.new MyThread();
thread1.start();
try {
System.out.println("线程"+Thread.currentThread().getName()+"等待");
thread1.join();
System.out.println("线程"+Thread.currentThread().getName()+"继续执行");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class MyThread extends Thread{
@Override
public void run() {
System.out.println("进入线程"+Thread.currentThread().getName());
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println("线程"+Thread.currentThread().getName()+"执行完毕");
}
}
}
|
12345678 9101112131415 1617181920212223242526272829 30 |
test de classe publique { public static void main(String[] args) lance IOException { Système .out.println("Enter thread"+Thread.currentThread().getName()); Test test = new Test(); MyThread thread1 = test.new MyThread( ) ; thread1.start(); essayez { System.out.println("Thread"+Thread.currentThread().getName()+"Attendez " ); thread1.join(); System.out.println("Thread"+Thread.currentThread().getName()+"Continuer l'exécution"); 🎜> } catch (InterruptedException e) { 🎜> } > entrez le fil de discussion"+Thread.currentThread().getName()); essayez le { fil de discussion. currentThread().sleep(5000); } catch (InterruptedEx ception e ) { // TODO : gérer l'exception "); } >} |
Résultat de sortie :
On peut voir que lorsque la méthode thread1.join() est appelée, le thread principal sera entrez wait, puis attendez que thread1 termine son exécution avant de continuer.
En fait, l'appel de la méthode join appelle la méthode wait de Object. Cela peut être connu en visualisant le code source :
wait. méthode Cela fera entrer le thread dans un état bloqué, libérera le verrou détenu par le thread et remettra les autorisations d'exécution du processeur.
Puisque la méthode wait amènera le thread à libérer le verrou de l'objet, la méthode join amènera également le thread à libérer le verrou détenu sur un objet. L'utilisation spécifique de la méthode wait est donnée dans l'article suivant.
6) méthode d'interruption
Interruption, comme son nom l'indique, signifie interruption. L'appel de la méthode d'interruption seul peut amener le thread à l'état bloqué à lever une exception, c'est-à-dire qu'il peut être utilisé pour interrompre un thread à l'état bloqué. De plus, la méthode d'interruption et la méthode isInterrupted() sont utilisées pour arrêter le thread ; fil en cours d'exécution.
Voici un exemple :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public class Test {
public static void main(String[] args) throws IOException {
Test test = new Test();
MyThread thread = test.new MyThread();
thread.start();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
}
thread.interrupt();
}
class MyThread extends Thread{
@Override
public void run() {
try {
System.out.println("进入睡眠状态");
Thread.currentThread().sleep(10000);
System.out.println("睡眠完毕");
} catch (InterruptedException e) {
System.out.println("得到中断异常");
}
System.out.println("run方法执行完毕");
}
}
}
|
12345678 910111213141516171819202122232425262728 |
Test en classe publique { thread = test.new MyThread(); thread.start(); essayez { Thread.currentThread( .sleep(2000); la classe MyThread étend le fil de discussion{ @Override public void run() { essayez { System.out.println("Enter Sleep state"); Thread.currentThread().sleep(10000); System.out .println("Veille terminée"); } catch (InterruptedException e) { System.out.println ("" Anomalie obtenue "); } System.out.println 🎜> } }} |
Résultat de sortie :
Comme on peut le voir à partir d'ici, le fil interrompu peut être interrompu via la méthode d'interruption. Alors, un thread dans un état non bloquant peut-il être interrompu ? Regardez l'exemple suivant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public class Test {
public static void main(String[] args) throws IOException {
Test test = new Test();
MyThread thread = test.new MyThread();
thread.start();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
}
thread.interrupt();
}
class MyThread extends Thread{
@Override
public void run() {
int i = 0;
while(i
System.out.println(i+" while循环");
i++;
}
}
}
}
|
12 345678910111213141516 17181920212223 2425 |
Test en classe publique { IOException { Test test = nouveau Test(); Fil de discussion MyThread = test.new MyThread(); thread.start(); essayer { 🎜> thread.interrupt (); ) { int i = 0; While (I & LT; Integer.max_value) { System.out.println (I+"Pendant le cycle" ); 🎜>i++; } } }}
|
corps>
Lorsque vous exécutez ce programme, vous constaterez que la boucle while continuera à s'exécuter jusqu'à ce que la valeur de la variable i dépasse Integer.MAX_VALUE. Par conséquent, l’appel direct de la méthode d’interruption ne peut pas interrompre un thread en cours d’exécution.
Mais si le thread en cours d'exécution peut être interrompu avec isInterrupted(), car appeler la méthode d'interruption équivaut à définir l'indicateur d'interruption sur true, alors vous pouvez interrompre le thread en appelant isInterrupted() pour déterminer si l'interruption le drapeau est défini. Par exemple, le code suivant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public class Test {
public static void main(String[] args) throws IOException {
Test test = new Test();
MyThread thread = test.new MyThread();
thread.start();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
}
thread.interrupt();
}
class MyThread extends Thread{
@Override
public void run() {
int i = 0;
while(!isInterrupted() && i
System.out.println(i+" while循环");
i++;
}
}
}
}
|
1 2
3
4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class MyThread extends Thread{
private volatile boolean isStop = false;
@Override
public void run() {
int i = 0;
while(!isStop){
i++;
}
}
public void setStop(boolean stop){
this.isStop = stop;
}
}
|
56789 1011121314151617181920212223 2425
|
cours public Test { lance une exception IO{ Test test = new Test( ); MyThread thread = test.new MyThread(); > try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { > thread.interrupt(); public void run( ) { int i = 0; while(!isInterrupted() && i
|
Lorsque vous l'exécutez, vous constaterez qu'après avoir imprimé plusieurs valeurs , la boucle while arrête l'impression. Cependant, il n'est généralement pas recommandé d'interrompre le thread de cette manière. Généralement, un attribut isStop est ajouté à la classe MyThread pour marquer s'il faut terminer la boucle while, puis la valeur de isStop est déterminée dans la boucle while.
12 345678910 11121314 |
la classe MyThread étend le fil de discussion{ private volatile boolean isStop = false; while(!isStop ){ i++; } } public void set Stop(boolean stop ){ this.isStop = stop; } } |
Ensuite, vous pouvez terminer la boucle while en appelant la méthode setStop à l'extérieur.
7) méthode stop
La méthode stop est une méthode abandonnée et c'est une méthode dangereuse. Parce que l'appel de la méthode stop mettra directement fin à l'appel de la méthode run et générera une erreur ThreadDeath. Si le thread détient un verrou d'objet, le verrou sera complètement libéré, ce qui entraînera un statut d'objet incohérent. Par conséquent, la méthode stop ne sera fondamentalement pas utilisée.
8) méthode destroy
La méthode destroy est également une méthode abandonnée. En principe, il ne sera pas utilisé.
Voici plusieurs méthodes liées aux attributs du fil :
1) getId
Utilisé pour obtenir l'ID du fil
2) getName et setName
Utilisé pour obtenir ou définir le nom du fil de discussion.
3) getPriority et setPriority
sont utilisés pour obtenir et définir la priorité des threads.
4) setDaemon et isDaemon
sont utilisés pour définir si le thread devient un thread démon et pour déterminer si le thread est un thread démon.
La différence entre les threads démons et les threads utilisateur est que le thread démon dépend du thread qui l'a créé, contrairement au thread utilisateur. Pour donner un exemple simple : si un thread démon est créé dans le thread principal, lorsque la méthode principale aura fini de s'exécuter, le thread démon mourra également. Le thread utilisateur ne le fera pas. Le thread utilisateur continuera à s'exécuter jusqu'à ce qu'il soit terminé. Dans la JVM, un thread garbage collector est un thread démon.
La classe Thread a une méthode statique couramment utilisée currentThread() pour obtenir le thread actuel.
La plupart des méthodes de la classe Thread ont été mentionnées ci-dessus, alors comment les appels de méthode dans la classe Thread provoqueront-ils des changements dans l'état du thread ? L'image suivante est une amélioration par rapport à l'image ci-dessus :