1
2
3
|
sleep(long millis) //参数为毫秒
sleep(long millis,int nanoseconds) //第一参数为毫秒,第二个参数为纳秒
|
123 |
sleep(long millis) //Der Parameter ist Millisekunden sleep(long millis,int nanoseconds) //Der erste Parameter ist Millisekunden, der zweite Parameter ist Nanosekunden |
Ruhezustand ist gleichbedeutend damit, den Thread schlafen zu lassen, die CPU zu übergeben und die CPU andere Aufgaben ausführen zu lassen.
Beachten Sie jedoch, dass die Schlafmethode die Sperre nicht aufhebt. Das heißt, wenn der aktuelle Thread eine Sperre für ein Objekt hält, können andere Threads nicht auf das Objekt zugreifen, selbst wenn Die Schlafmethode wird aufgerufen. Es wird deutlich, wenn Sie sich das folgende Beispiel ansehen:
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 |
öffentlicher Klassentest { 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(); } @Override public void run() { synchronisiert (object) { i++; System.out .println("i:"+ i); try { System. out.println("Thread"+Thread.currentThread().getName()+"Enter Sleep"); Thread.currentThread().sleep(10000); } Catch ( InterruptedException e) { } System .out.println("Thread"+Thread.currentThread().getName()+"Sleep End"); i++ ; System.out.println("i:"+ i); } } }} |
Ausgabeergebnisse:
Bestimmte Aufgaben wurden nicht ausgeführt. Erst wenn Thread-0 die Ausführung abschließt und Thread-0 die Objektsperre aufhebt, beginnt Thread-1 mit der Ausführung.
Beachten Sie, dass beim Aufruf der Sleep-Methode die InterruptedException abgefangen oder an die obere Ebene geworfen werden muss. Wenn die Thread-Ruhezeit abgelaufen ist, wird sie möglicherweise nicht sofort ausgeführt, da die CPU zu diesem Zeitpunkt möglicherweise andere Aufgaben ausführt. Der Aufruf der Sleep-Methode entspricht also dem Versetzen des Threads in einen blockierenden Zustand.
4) Yield-Methode Der Aufruf der Yield-Methode führt dazu, dass der aktuelle Thread CPU-Berechtigungen übergibt und die CPU andere Threads ausführen lässt. Es ähnelt der Schlafmethode und hebt die Sperre ebenfalls nicht auf. Yield kann jedoch nicht die spezifische Zeit für die Übergabe der CPU steuern. Darüber hinaus kann die Yield-Methode nur Threads mit derselben Priorität die Möglichkeit geben, CPU-Ausführungszeit zu erhalten. Beachten Sie, dass der Aufruf der Yield-Methode den Thread nicht in den Blockierungszustand versetzt, sondern ihn in den Bereitschaftszustand zurückversetzt. Es muss nur darauf gewartet werden, dass die CPU-Ausführungszeit wiederhergestellt wird, was sich von der unterscheidet Schlafmethode. 5) Join-Methode Die Join-Methode hat drei überladene Versionen:
1
2
3
1
2
3
|
join()
join(long millis) //参数为毫秒
join(long millis,int nanoseconds) //第一参数为毫秒,第二个参数为纳秒
|
|
join()join(long millis) //Der Parameter ist Millisekundenjoin(long millis,int nanoseconds) //Der erste Parameter ist Millisekunden, der zweite Parameter ist Nanosekunden |
Wenn die Methode thread.join im Hauptthread aufgerufen wird, wartet die Hauptmethode darauf, dass der Thread-Thread die Ausführung abschließt, oder wartet eine bestimmte Zeit. Wenn die Join-Methode ohne Parameter aufgerufen wird, warten Sie, bis der Thread die Ausführung abgeschlossen hat. Wenn die Join-Methode mit einem angegebenen Zeitparameter aufgerufen wird, warten Sie auf ein bestimmtes Ereignis.
Sehen Sie sich das folgende Beispiel an:
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 |
public class Test { public static void main(String[] args) throws IOException { System .out.println("Enter thread"+Thread.currentThread().getName()); Test test = new Test(); MyThread thread1 = test.new MyThread( ) ; thread1.start(); try { System.out.println("Thread"+Thread.currentThread().getName()+"Wait " ); thread1.join(); System.out.println("Thread"+Thread.currentThread().getName()+"Ausführung fortsetzen"); 🎜> } Catch (InterruptedException e) { 🎜> } > enter Thread"+Thread.currentThread().getName()); try { Thread. currentThread().sleep(5000); } Catch (InterruptedException e ) { Ausnahme behandeln ");. } }} |
Ausgabeergebnis:
Es ist ersichtlich, dass der Haupt-Thread aufgerufen wird, wenn die Methode thread1.join() aufgerufen wird Wechseln Sie in den Wartezustand und warten Sie, bis die Ausführung von Thread1 abgeschlossen ist, bevor Sie fortfahren.
Tatsächlich ruft der Aufruf der Join-Methode die Wartemethode von Object auf. Dies kann durch Anzeigen des Quellcodes festgestellt werden:
wait Methode Dies führt dazu, dass der Thread in einen blockierten Zustand wechselt, die vom Thread gehaltene Sperre aufhebt und CPU-Ausführungsberechtigungen übergibt.
Da die Wartemethode den Thread dazu veranlasst, die Objektsperre aufzuheben, bewirkt die Join-Methode auch, dass der Thread die für ein Objekt gehaltene Sperre aufhebt. Die spezifische Verwendung der Wartemethode wird im folgenden Artikel beschrieben.
6) Interrupt-Methode
Interrupt bedeutet, wie der Name schon sagt, Unterbrechung. Der alleinige Aufruf der Interrupt-Methode kann dazu führen, dass der Thread im blockierten Zustand eine Ausnahme auslöst, d laufender Thread.
Hier ist ein Beispiel:
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 |
öffentlicher Klassentest { thread = test.new MyThread(); thread.start(); try { Thread.currentThread() .sleep(2000); 🎜> Versuchen Sie es mit {System.out.println("Enter Sleep state");Thread.currentThread().sleep(10000);System.out. println("Schlaf abgeschlossen"); (InterruptedException e) { use using ‐ using System.out.println's("Erhalten einer Interrupt-Ausnahme" 🎜> } } } |
Ausgabeergebnis:
Wie hier zu sehen ist, kann der unterbrochene Thread durch die Interrupt-Methode unterbrochen werden. Kann ein Thread in einem nicht blockierenden Zustand unterbrochen werden? Schauen Sie sich das folgende Beispiel an:
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 |
öffentlicher Klassentest { IOException-Test test = neuer Test(); MyThread thread = test.new MyThread(); thread.start(); try { 🎜> thread.interrupt (); ) { int i = 0; While (I & LT; Integer.max_value) { System.out.println (I+"While Cycle" ); 🎜> i++;
|
tbody>
Wenn Sie dieses Programm ausführen, werden Sie feststellen, dass die while-Schleife so lange ausgeführt wird, bis der Wert der Variablen i Integer.MAX_VALUE überschreitet. Daher kann der direkte Aufruf der Interrupt-Methode den laufenden Thread nicht unterbrechen.
Wenn der laufende Thread jedoch mit isInterrupted () unterbrochen werden kann, da der Aufruf der Interrupt-Methode dem Setzen des Interrupt-Flags auf true entspricht, können Sie den Thread durch Aufruf von isInterrupted () unterbrechen, um festzustellen, ob der Interrupt erfolgt Flag ist gesetzt. Zum Beispiel der folgende Code:
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
|
öffentlicher Klassentest wirft IOException { Test test = neuer 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
|
Wenn Sie es ausführen, werden Sie feststellen, dass nach dem Drucken mehrerer Werte , stoppt die while-Schleife den Druckvorgang. Es wird jedoch im Allgemeinen nicht empfohlen, den Thread auf diese Weise zu unterbrechen. Im Allgemeinen wird der MyThread-Klasse ein Attribut isStop hinzugefügt, um zu markieren, ob die while-Schleife beendet werden soll, und dann wird der Wert von isStop bestimmt die while-Schleife.
12 345678910 11121314 |
Klasse MyThread erweitert Thread{ private volatile boolean isStop = false; while(!isStop ){ i++; } } public void set Stop(boolean stop ){ this.isStop = stop; } } |
Anschließend können Sie die while-Schleife beenden, indem Sie die setStop-Methode außerhalb aufrufen.
7) Stop-Methode
Die Stop-Methode ist eine aufgegebene Methode und eine unsichere Methode. Da der Aufruf der Stop-Methode den Aufruf der Run-Methode direkt beendet und einen ThreadDeath-Fehler auslöst. Wenn der Thread eine Objektsperre hält, wird die Sperre vollständig aufgehoben, was zu einem inkonsistenten Objektstatus führt. Daher wird die Stoppmethode grundsätzlich nicht verwendet.
8) Zerstörungsmethode
Die Zerstörungsmethode ist ebenfalls eine aufgegebene Methode. Wird grundsätzlich nicht verwendet.
Im Folgenden sind mehrere Methoden im Zusammenhang mit Thread-Attributen aufgeführt:
1) getId
Wird verwendet, um die Thread-ID abzurufen
2) getName und setName
Wird verwendet, um den Thread-Namen abzurufen oder festzulegen.
3) getPriority und setPriority
werden verwendet, um die Thread-Priorität abzurufen und festzulegen.
4) setDaemon und isDaemon
werden verwendet, um festzulegen, ob der Thread ein Daemon-Thread wird, und um zu bestimmen, ob der Thread ein Daemon-Thread ist.
Der Unterschied zwischen Daemon-Threads und Benutzer-Threads besteht darin, dass der Daemon-Thread von dem Thread abhängt, der ihn erstellt hat, während dies beim Benutzer-Thread nicht der Fall ist. Um ein einfaches Beispiel zu nennen: Wenn im Hauptthread ein Daemon-Thread erstellt wird und die Ausführung der Hauptmethode beendet ist, stirbt auch der Daemon-Thread. Der Benutzerthread wird nicht weiter ausgeführt, bis er abgeschlossen ist. In der JVM ist ein Garbage-Collector-Thread ein Daemon-Thread.
Die Thread-Klasse verfügt über eine häufig verwendete statische Methode currentThread(), um den aktuellen Thread abzurufen.
Die meisten Methoden in der Thread-Klasse wurden oben erwähnt. Wie bewirken die Methodenaufrufe in der Thread-Klasse also Änderungen im Thread-Status? Das folgende Bild ist eine Verbesserung zum obigen Bild: