Dieser Artikel vermittelt Ihnen relevantes Wissen über Java, das hauptsächlich die Probleme im Zusammenhang mit den vier Möglichkeiten zur Implementierung von Multithreading löst, einschließlich der Vererbung der Thread-Klasse, der Implementierung der Callable-Schnittstelle zum Erstellen von Thread-Threads über den FutureTask-Wrapper und der Verwendung ExecutorService, Callable und Future implementieren Multithreading, das Ergebnisse usw. zurückgibt. Schauen wir sie uns gemeinsam an. Ich hoffe, dass es für alle hilfreich ist.
Empfohlenes Lernen: „Java-Video-Tutorial“
JavaEs gibt vier Hauptmethoden zum Implementieren von Multithreading:
1. Vier Möglichkeiten zur Implementierung von Multithreading
Die Thread-Klasse ist im Wesentlichen eine Instanz, die die Runnable-Schnittstelle implementiert und eine Instanz eines Threads darstellt. Die einzige Möglichkeit, einen Thread zu starten, ist die start()-Instanzmethode der Thread-Klasse. Die start()-Methode ist eine native Methode, die einen neuen Thread startet und die run()-Methode ausführt. Es ist sehr einfach, Multithreading auf diese Weise zu implementieren, indem Sie Thread direkt durch Ihre eigene Klasse erweitern und die run()-Methode überschreiben. Sie können einen neuen Thread starten und Ihre eigene definierte run()-Methode ausführen. Beispiel:
public class MyThread extends Thread { public void run() { System.out.println("MyThread.run()"); } } MyThread myThread1 = new MyThread(); MyThread myThread2 = new MyThread(); myThread1.start(); myThread2.start();
Wenn Ihre Klasse eine andere Klasse erweitert hat, können Sie zu diesem Zeitpunkt eine Runnable-Schnittstelle wie folgt implementieren:
public class MyThread extends OtherClass implements Runnable { public void run() { System.out.println("MyThread.run()"); } }
MyThread myThread = new MyThread(); Thread thread = new Thread(myThread); thread.start();
public void run() { if (target != null) { target.run(); } }
3. Implementieren Sie die Callable-Schnittstelle, um Thread-Threads über den FutureTask-Wrapper zu erstellen.
public interface Callable<V> { V call() throws Exception; } public class SomeCallable<V> extends OtherClass implements Callable<V> { @Override public V call() throws Exception { // TODO Auto-generated method stub return null; } }
Callable<V> oneCallable = new SomeCallable<V>(); //由Callable<Integer>创建一个FutureTask<Integer>对象: FutureTask<V> oneTask = new FutureTask<V>(oneCallable); //注释:FutureTask<Integer>是一个包装器,它通过接受Callable<Integer>来创建,它同时实现了Future和Runnable接口。 //由FutureTask<Integer>创建一个Thread对象: Thread oneThread = new Thread(oneTask); oneThread.start(); //至此,一个线程就创建完成了。
4. und Future zum Implementieren von Threads, die Ergebnisse zurückgeben
ExecutorService. Die drei Schnittstellen Callable und Future gehören tatsächlich zum Executor-Framework. Der Thread, der das Ergebnis zurückgibt, ist eine neue Funktion, die in JDK1.5 eingeführt wurde. Mit dieser Funktion müssen Sie sich nicht mehr viel Mühe geben, um den Rückgabewert zu erhalten. Und selbst wenn Sie es selbst implementieren, kann es voller Lücken sein.
Aufgaben, die Werte zurückgeben können, müssen die Callable-Schnittstelle implementieren. Ebenso müssen Aufgaben, die keinen Wert zurückgeben, die Runnable-Schnittstelle implementieren.
Hinweis: Die Get-Methode blockiert, das heißt: Der Thread gibt kein Ergebnis zurück und die Get-Methode wartet ewig.
Im Folgenden finden Sie ein vollständiges Multithread-Testbeispiel mit den zurückgegebenen Ergebnissen. Es wurde unter JDK1.5 verifiziert und kann problemlos direkt verwendet werden. Der Code lautet wie folgt:
import java.util.concurrent.*; import java.util.Date; import java.util.List; import java.util.ArrayList; /** * 有返回值的线程 */ @SuppressWarnings("unchecked") public class Test { public static void main(String[] args) throws ExecutionException, InterruptedException { System.out.println("----程序开始运行----"); Date date1 = new Date(); int taskSize = 5; // 创建一个线程池 ExecutorService pool = Executors.newFixedThreadPool(taskSize); // 创建多个有返回值的任务 List<Future> list = new ArrayList<Future>(); for (int i = 0; i < taskSize; i++) { Callable c = new MyCallable(i + " "); // 执行任务并获取Future对象 Future f = pool.submit(c); // System.out.println(">>>" + f.get().toString()); list.add(f); } // 关闭线程池 pool.shutdown(); // 获取所有并发任务的运行结果 for (Future f : list) { // 从Future对象上获取任务的返回值,并输出到控制台 System.out.println(">>>" + f.get().toString()); } Date date2 = new Date(); System.out.println("----程序结束运行----,程序运行时间【" + (date2.getTime() - date1.getTime()) + "毫秒】"); } } class MyCallable implements Callable<Object> { private String taskNum; MyCallable(String taskNum) { this.taskNum = taskNum; } public Object call() throws Exception { System.out.println(">>>" + taskNum + "任务启动"); Date dateTmp1 = new Date(); Thread.sleep(1000); Date dateTmp2 = new Date(); long time = dateTmp2.getTime() - dateTmp1.getTime(); System.out.println(">>>" + taskNum + "任务终止"); return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】"; } }2. Multithreading-bezogenes Wissen 1 Was ist der Unterschied zwischen Runnable und Callable? ·
Der Hauptunterschied besteht darin, dass die Run-Methode der Runnable-Schnittstelle keinen Rückgabewert hat.
·Die Thread-Objektaufrufe beginnen, den Thread zu öffnen, und ermöglichen es der JVM, die Ausführungsmethode im geöffneten Thread aufzurufen. Durch Aufrufen der Startmethode kann der Thread gestartet und in den Bereitschaftszustand versetzt werden ist nur eine übliche Thread-Methode oder wird im Hauptthread ausgeführt.Aufrufbare Schnittstellenaufrufmethode ermöglicht das Auslösen von Ausnahmen und das Abrufen von Ausnahmeinformationen
2. Wie startet man einen neuen Thread und was ist der Unterschied zwischen dem Aufruf der Start- und Ausführungsmethoden? ?·
Das Thread-Objekt ruft die Ausführungsmethode auf, ohne den Thread zu starten. Nur Objekte rufen Methoden auf.
·
3. Grundlegende Thread-bezogene Methoden?Zu den grundlegenden Methoden im Zusammenhang mit Threads gehören Wait, Notify, NotifyAll, Sleep, Join, Yield usw.
· Thread-Warten (Wait) Der Thread, der diese Methode aufruft, wechselt in den Wartezustand und wartet nur auf Benachrichtigungen von Ein anderer Thread wird unterbrochen oder es wird darauf hingewiesen, dass nach dem Aufruf der Methode wait() die Sperre des Objekts aufgehoben wird. Daher wird die Wartemethode im Allgemeinen in synchronisierten Methoden oder synchronisierten Codeblöcken verwendet.
· Thread yield (yield) yield führt dazu, dass der aktuelle Thread die CPU-Ausführungszeitscheibe zurückgibt und erneut mit anderen Threads um die CPU-Zeitscheibe konkurriert. Im Allgemeinen haben Threads mit hoher Priorität eine größere Chance, erfolgreich um CPU-Zeitscheiben zu konkurrieren, dies gilt jedoch nicht unbedingt. Einige Betriebssysteme reagieren nicht empfindlich auf Thread-Priorität.
· Thread-Unterbrechung (Interrupt) Die ursprüngliche Absicht der Unterbrechung eines Threads besteht darin, dem Thread ein Benachrichtigungssignal zu geben, das sich auf ein Interrupt-Flag innerhalb des Threads auswirkt. Aus diesem Grund ändert der Thread selbst seinen Status (z. B. Blockierung, Beendigung usw.) nicht ()-Methode eines Threads im aktuellen Thread wechselt in den Blockierungszustand und kehrt zum Beenden des aktuellen Threads vom Blockierungszustand in den Bereitschaftszustand zurück
· Thread-Wake-up (Notify)-Methode notify() in der Object-Klasse. Weckt einen einzelnen Thread auf, der auf dem Monitor dieses Objekts wartet. Wenn alle Threads auf dieses Objekt warten, wird einer der Threads zum Aufwecken ausgewählt Die Auswahl ist willkürlich und erfolgt, wenn eine Entscheidung über die Implementierung getroffen wird. Die Methode wait() wartet auf dem Monitor des Objekts, bis der aktuelle Thread die Sperre für dieses Objekt aufgibt, bevor der Thread aktiviert wird Der aufgeweckte Thread kann weiterhin auf normale Weise mit allen anderen aktiv synchronisierten Threads ausgeführt werden. Eine ähnliche Methode ist notifyAll(), die alle auf dem Monitor wartenden Threads wieder aufweckt.
5. Was ist der Unterschied zwischen wait() und sleep()?
· ② Bezüglich der Freigabe der Sperre: wait(): Die Sperre wird freigegeben während des Wartevorgangs; Sleep(): Die Sperre wird während des Wartevorgangs nicht aufgehoben
· ③ Anwendungsbereich: Wait(): muss in synchronisierten Codeblöcken verwendet werden;
· ④ Müssen Sie Ausnahmen abfangen?
Multi-Threading erfolgt gleichzeitig. Eine CPU kann zu einem bestimmten Zeitpunkt nur ein Programm ausführen, das heißt, sie kann nur einen Prozess gleichzeitig ausführen. Die CPU wechselt ständig zwischen diesen Prozessen und jeder Thread wird einmal ausgeführt. Da die Ausführungsgeschwindigkeit der CPU im Verhältnis zu unserer Wahrnehmung zu hoch ist, haben wir zwar das Gefühl, dass mehrere Prozesse gleichzeitig ausgeführt werden, obwohl die CPU die Ausführung zwischen mehreren Prozessen wechselt.
Die CPU wechselt zwischen mehreren Prozessen. Wenn wir zu viele Programme öffnen, wird auch die Zeit, die die CPU benötigt, um zu jedem Prozess zu wechseln, länger und wir werden auch das Gefühl haben, dass die Maschine langsamer läuft. Daher kann die sinnvolle Verwendung von Multithreading die Effizienz verbessern, eine umfassende Verwendung führt jedoch nicht zu einer Verbesserung der Effizienz.
Empfohlenes Lernen: „
Java-Video-Tutorial“
Das obige ist der detaillierte Inhalt vonVier Möglichkeiten zur Implementierung von Multithreading in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!