Multithreading ist ein sehr wichtiger Wissenspunkt in Java. Ich hoffe, dass Sie es beherrschen.
Methode eins Thread.sleep
Methode zwei ExecutorService
Methode drei Thread .join
Methode 4 Thread.yield und Thread.activeCount
Ich bin beim Schreiben von Code auf ein solches Szenario gestoßen. Ich muss den Ausführungsstatus jedes Unterthreads beobachten. Wenn keine Verarbeitung durchgeführt wird, werden andere Unterthreads nach der main
-Methode geschlossen ist mit der Ausführung fertig, wodurch es unmöglich ist, den detaillierten Ausführungsstatus aller Unterthreads zu beobachten, sodass der Hauptthread warten muss, bis die Ausführung aller Unterthreads abgeschlossen ist. In der Vergangenheit bestand der schlampigere Ansatz darin, main
zur Funktion Thread.sleep(time)
Diese Methode ist jedoch nicht perfekt, da die künstliche Einstellung der Wartezeit nicht die beste Vorgehensweise ist. Daher habe ich einige Informationen und Blogs überprüft. Hier sind vier Methoden, um diesen Zweck zu erreichen >
public static void main(String[] args) throws InterruptedException{ for(int i=0; i<10; i++){ new Thread("subthread" + i){ @Override public void run() { try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "finished"); }catch(InterruptedException e){ e.printStackTrace(); } } }.start(); } Thread.sleep(2000); System.out.println("main thread finished"); }Methode 2 ExecutorService kann die Thread-Pool-Implementierung verwenden. Häufig verwendete Thread-Pool-Objekte sind alle Implementierungen der
subthread0finished subthread1finished subthread2finished subthread6finished subthread4finished subthread5finished subthread3finished subthread9finished subthread8finished subthread7finished main thread finished
ExecutorService
Diese Methode weist einige kleinere Mängel auf Der Hauptthread wird tatsächlich vor dem untergeordneten Thread ausgeführt. Daher kann diese Methode nur sicherstellen, dass der untergeordnete Thread vollständig ausgeführt wird, bevor das Programm beendet wird. Es gibt jedoch keine Garantie dafür, dass der Hauptthread ausgeführt wird, nachdem der untergeordnete Thread ausgeführt wurde. Die Ausführung des Threads ist abgeschlossen. Daher muss der Code geändert werden, um eine angemessenere Wartezeit festzulegen und darauf zu warten, dass die Ausführung des Unterthreads abgeschlossen ist: shutdown
public static void main(String[] args) { // 创建一个ExecutorService ExecutorService ex = Executors.newCachedThreadPool(); for(int i=0; i<10; i++){ // 添加 task ex.submit(new Thread("subthread" + i){ @Override public void run() { try{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "finished"); }catch(InterruptedException e){ e.printStackTrace(); } } }); } // 使用shutdown 会通知executorservice 停止添加其它task 它会等待所有子线程运行结束才退出Java进程 ex.shutdown(); System.out.println("main thread finished"); }Sie können sehen, dass der vom Hauptthread ausgeführte Inhalt am Ende ausgegeben wird. Diese Methode muss die Wartezeit wie Methode 1 festlegen, was keine perfekte Methode ist.Methode 3 Thread. join
awaitTermination(time, timeunit)
-Thread erstellt. Wenn also
im-Thread ausgeführt wird, wird gewartet, bis die Ausführung des untergeordneten Threads abgeschlossen ist, bevor mit der Ausführung des
-Threads fortgefahren wird. Der Code lautet wie folgt:main thread finished pool-1-thread-3finished pool-1-thread-4finished pool-1-thread-2finished pool-1-thread-1finished pool-1-thread-5finished pool-1-thread-7finished pool-1-thread-8finished pool-1-thread-6finished pool-1-thread-9finished pool-1-thread-10finished
public static void main(String[] args) { // 创建一个ExecutorService ExecutorService ex = Executors.newCachedThreadPool(); for(int i=0; i<10; i++){ // 添加 task ex.submit(new Thread("subthread" + i){ @Override public void run() { try{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "finished"); }catch(InterruptedException e){ e.printStackTrace(); } } }); } // 使用shutdown 会通知executorservice 停止添加其它task 它会等待所有子线程运行结束才退出Java进程 ex.shutdown(); try { // 设置等待时间等待子线程运行完毕 if(!ex.awaitTermination(2000, TimeUnit.MILLISECONDS)){ // 等待时间内子线程并未全部运行完毕就直接关闭 ex.shutdownNow(); } }catch(InterruptedException e){ ex.shutdownNow(); } System.out.println("main thread finished"); }
thread.join
Der Vorteil dieser Methode im Vergleich zu den beiden oben genannten Methoden besteht darin, dass keine Wartezeit festgelegt werden muss.main
main
Methode 4 Thread.yield und Thread.activeCount某一个子线程.join
main
Erklären wir zunächst die Funktionen dieser beiden Methoden. Für Laien ist eine Konzession. Der aktuelle Thread , der diese Methode aufruft, belegt die Rechte von
. Dies bedeutet jedoch nicht, dass der aktuelle Thread nicht mehr ausgeführt wird. Die Methodegibt die Anzahl der aktiven Threads in der Thread-Gruppe zurück, die dem aktuell aufrufenden Thread entspricht. Der Parameter
bezieht sich auf die Thread-Gruppe, die dem erstellten Thread entspricht. Wenn dieser Parameter nicht angegeben ist, befindet sich der Thread, der erstellt wurde, in derselben Thread-Gruppe. Der Code lautet wie folgt:pool-1-thread-1finished pool-1-thread-5finished pool-1-thread-4finished pool-1-thread-9finished pool-1-thread-8finished pool-1-thread-3finished pool-1-thread-2finished pool-1-thread-7finished pool-1-thread-6finished pool-1-thread-10finished main thread finished
public static void main(String[] args) throws InterruptedException{ List<Thread> list = new ArrayList<>(); for(int i=0; i<10; i++){ Thread t = new Thread("subthread" + i){ @Override public void run() { try{ Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "finished"); }catch(InterruptedException e){ e.printStackTrace(); } } }; list.add(t); t.start(); } for(Thread item : list){ item.join(); } System.out.println("main thread finished"); }
Thread.yield
Ein sehr wichtiger Punkt ist, dass 放弃
auf 2 gesetzt ist. Ja. Einige Blogs setzen es auf 1, aber 1 führt zu einer Endlosschleife und der Hauptthread kann dies nicht Der Grund dafür ist, dass jeder denkt, dass nach dem Ausschließen der Sub-Threads in der Thread-Gruppe, in der sich der Haupt-Thread befindet, nur noch der Haupt-Thread übrig ist. Dies ist beispielsweise nicht der Fall, wenn wir Folgendes ausführen Code: CPU
subthread1finished subthread2finished subthread0finished subthread3finished subthread6finished subthread5finished subthread4finished subthread9finished subthread7finished subthread8finished main thread finished
Thread.activeCount
Ausgabe: ThreadGroup
public static void main(String[] args) { // 关键参数 int defaultThreadNum = 2; for(int i=0; i<10 ;i++){ new Thread("subthread" + i){ @Override public void run() { try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "finished"); }catch(InterruptedException e){ e.printStackTrace(); } } }.start(); } while(Thread.activeCount() > defaultThreadNum){ // 当活跃线程数大于设定的默认线程数的时候 主线程让步 Thread.yield(); } System.out.println("main thread finished"); }Sie können sehen, dass es in der Thread-Gruppe, in der sich der Haupt-Thread befindet, einen weiteren Thread namens
gibt. Nach dem Ausschließen aller untergeordneten Threads gibt es also einen Es sind noch 2 Threads übrig, daher muss der Schwellenwert für die Schleifenbeurteilung (
) auf 2 gesetzt werden.Diese Methode muss auch nicht die Wartezeit festlegen defaultthreadnum
Monitor Ctrl-Break
defaultThreadNum
php5 non -Der Unterschied zwischen Thread-sicher und Thread-sicher
Das obige ist der detaillierte Inhalt vonVier Möglichkeiten, den Hauptthread herunterzufahren, nachdem alle Unterthread-Aufgaben abgeschlossen sind. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!