Heim  >  Artikel  >  Java  >  Fragen zum Java-Multithreading-Interview

Fragen zum Java-Multithreading-Interview

(*-*)浩
(*-*)浩Original
2019-12-11 15:05:352813Durchsuche

Fragen zum Java-Multithreading-Interview

Was ist ein Thread?

Thread ist die kleinste Einheit, die das Betriebssystem ausführen kann. Er ist im Prozess enthalten und die eigentliche Betriebseinheit im Prozess. Programmierer können es für die Multiprozessorprogrammierung verwenden, und Sie können Multithreading verwenden, um rechenintensive Aufgaben zu beschleunigen. (Empfohlene Studie: Java-Interviewfragen)

Wenn es beispielsweise 100 Millisekunden dauert, bis ein Thread eine Aufgabe erledigt, dann dauert es nur 10 Millisekunden, bis zehn Threads die Aufgabe erledigt haben .

Was ist der Unterschied zwischen einem Thread und einem Prozess?

Threads sind eine Teilmenge von Prozessen. Ein Prozess kann viele Threads haben und jeder Thread führt unterschiedliche Aufgaben parallel aus. Verschiedene Prozesse nutzen unterschiedliche Speicherplätze und alle Threads teilen sich denselben Speicherplatz. Jeder Thread verfügt über einen separaten Stapelspeicher zum Speichern lokaler Daten.

Wie implementiert man Threads in Java?

Zwei Möglichkeiten: Eine Instanz der java.lang.Thread-Klasse ist ein Thread, muss aber zur Ausführung die java.lang.Runnable-Schnittstelle aufrufen, da die Thread-Klasse selbst die aufgerufene Runnable-Schnittstelle ist , Sie können die Klasse java.lang.Thread erben oder die Runnable-Schnittstelle direkt aufrufen, um die run()-Methode zum Implementieren von Threads zu überschreiben.

Was sind die Funktionen und Unterschiede zwischen den Java-Schlüsselwörtern volatile und synchronisiert?

1, flüchtig

Die von ihr geänderte Variable behält keine Kopie und greift direkt auf den Hauptspeicher zu.

Im Java-Speichermodell gibt es einen Hauptspeicher und jeder Thread verfügt auch über einen eigenen Speicher (z. B. Register). Aus Leistungsgründen behält ein Thread eine Kopie der Variablen, auf die er zugreift, in seinem eigenen Speicher.

Auf diese Weise kann der Wert derselben Variablen im Speicher eines Threads zu einem bestimmten Zeitpunkt mit dem Wert im Speicher eines anderen Threads oder dem Wert im Hauptspeicher inkonsistent sein.

Das Deklarieren einer Variablen als flüchtig bedeutet, dass die Variable jederzeit von anderen Threads geändert wird und daher nicht im Thread-Speicher zwischengespeichert werden kann.

2, synchronisiert

Wenn es zum Ändern einer Methode oder eines Codeblocks verwendet wird, kann sichergestellt werden, dass höchstens ein Thread den Code gleichzeitig ausführt.

1. Wenn zwei gleichzeitige Threads auf den synchronisierten (diesen) Synchronisationscodeblock im selben Objekt zugreifen, kann jeweils nur ein Thread ausgeführt werden. Ein anderer Thread muss warten, bis der aktuelle Thread die Ausführung dieses Codeblocks abgeschlossen hat, bevor er diesen Codeblock ausführen kann.

2. Wenn jedoch ein Thread auf einen synchronisierten (diesen) synchronisierten Codeblock des Objekts zugreift, kann ein anderer Thread weiterhin auf den nicht synchronisierten (diesen) synchronisierten Codeblock im Objekt zugreifen.

3. Was besonders kritisch ist, ist, dass, wenn ein Thread auf einen synchronisierten (diesen) synchronisierten Codeblock des Objekts zugreift, andere Threads daran gehindert werden, auf alle anderen synchronisierten (diesen) synchronisierten Codeblöcke im Objekt zuzugreifen.

4. Wenn ein Thread auf einen synchronisierten (diesen) Synchronisationscodeblock eines Objekts zugreift, erhält er die Objektsperre dieses Objekts. Dadurch wird der Zugriff anderer Threads auf alle synchronisierten Codeteile des Objektobjekts vorübergehend blockiert.

5. Die oben genannten Regeln gelten auch für andere Objektsperren

Was sind die verschiedenen Thread-Lebenszyklen?

Wenn wir einen neuen Thread in einem Java-Programm erstellen, ist sein Status „Neu“. Wenn wir die start()-Methode des Threads aufrufen, wird der Status in Runnable geändert. Der Thread-Scheduler weist Threads im ausführbaren Thread-Pool CPU-Zeit zu und ändert ihren Status in „Wird ausgeführt“. Andere Thread-Status sind „Wartend“, „Blockiert“ und „Tot“.

Was verstehen Sie unter Thread-Priorität?

Jeder Thread hat eine Priorität, wenn er ausgeführt wird. Dies hängt jedoch von der Implementierung der Thread-Planung ab. Diese Implementierung ist abhängig vom Betriebssystem.

Wir können die Priorität von Threads definieren, aber dies garantiert nicht, dass Threads mit hoher Priorität vor Threads mit niedriger Priorität ausgeführt werden. Die Thread-Priorität ist eine int-Variable (von 1 bis 10), 1 steht für die niedrigste Priorität, 10 für die höchste Priorität.

Was ist ein Deadlock? Wie kann man Deadlocks analysieren und vermeiden?

Deadlock bezieht sich auf eine Situation, in der mehr als zwei Threads für immer blockiert sind. Diese Situation erfordert mindestens zwei weitere Threads und mehr als zwei Ressourcen.

Um den Deadlock zu analysieren, müssen wir uns den Thread-Dump der Java-Anwendung ansehen. Wir müssen herausfinden, welche Threads sich im Status BLOCKED befinden und auf welche Ressourcen sie warten. Jede Ressource hat eine eindeutige ID. Mithilfe dieser ID können wir herausfinden, welche Threads ihre Objektsperre bereits besitzen.

Das Vermeiden verschachtelter Sperren, die Verwendung von Sperren nur dort, wo sie benötigt werden, und das Vermeiden unbegrenzter Wartezeiten sind gängige Methoden zur Vermeidung von Deadlocks.

Was ist Thread-Sicherheit? Ist Vector eine Thread-sichere Klasse?

Wenn in dem Prozess, in dem sich Ihr Code befindet, mehrere Threads gleichzeitig ausgeführt werden, führen diese Threads diesen Code möglicherweise gleichzeitig aus. Wenn die Ergebnisse jedes Laufs mit denen von Single-Thread-Läufen übereinstimmen und die Werte anderer Variablen mit den Erwartungen übereinstimmen, ist dies Thread-sicher.

Eine Thread-sichere Zählerklasse verursacht keine Berechnungsfehler, wenn dasselbe Instanzobjekt von mehreren Threads verwendet wird. Natürlich können Sie Sammlungsklassen in zwei Gruppen einteilen: Thread-sichere und nicht Thread-sichere. Vector verwendet synchronisierte Methoden, um Thread-Sicherheit zu erreichen, während ArrayList, das ihm ähnlich ist, nicht Thread-sicher ist.

Wie stoppe ich einen Thread in Java?

Java bietet eine umfangreiche API, jedoch keine API zum Stoppen von Threads. JDK 1.0 verfügte ursprünglich über einige Steuerungsmethoden wie stop(), suspend() und resume(), diese wurden jedoch in nachfolgenden JDK-Versionen aufgrund potenzieller Deadlock-Bedrohungen veraltet. Danach stellten die Entwickler der Java-API keine kompatiblen und Thread-basierten Methoden zur Verfügung. sichere Möglichkeit, einen Thread zu stoppen.

Der Thread wird automatisch beendet, wenn die Methode run() oder call() ausgeführt wird. Wenn Sie einen Thread manuell beenden möchten, können Sie die flüchtige boolesche Variable verwenden, um die Schleife der Methode run() zu verlassen oder abzubrechen Die Aufgabe. Thread unterbrechen

Was ist ThreadLocal?

ThreadLocal wird verwendet, um lokale Variablen des Threads zu erstellen. Wir wissen, dass alle Threads eines Objekts seine globalen Variablen teilen Variablen, daher sind diese Variablen nicht threadsicher, wir können Synchronisationstechniken verwenden. Wenn wir jedoch keine Synchronisierung verwenden möchten, können wir ThreadLocal-Variablen auswählen.

Jeder Thread hat seine eigenen Thread-Variablen und sie können die Methode get()set() verwenden, um ihre Standardwerte abzurufen oder ihre Werte innerhalb des Threads zu ändern. ThreadLocal-Instanzen möchten normalerweise, dass der zugehörige Thread-Status private statische Eigenschaften ist.

Was sind die Unterschiede zwischen Sleep(), suspend() und wait()?

Thread.sleep() versetzt den aktuellen Thread zum angegebenen Zeitpunkt in den Status „Nicht ausführbar“. Der Thread enthält immer den Monitor des Objekts. Wenn sich beispielsweise ein Thread derzeit in einem synchronisierten Block oder einer synchronisierten Methode befindet, können andere Threads den Block oder die Methode nicht betreten. Wenn ein anderer Thread die Methode interrupt() aufruft, wird der „schlafende“ Thread aufgeweckt.

Hinweis: sleep() ist eine statische Methode. Dies bedeutet, dass es nur für den aktuellen Thread gültig ist. Ein häufiger Fehler besteht darin, t.sleep() aufzurufen (wobei t ein anderer Thread als der aktuelle Thread ist).

Auch wenn t.sleep() ausgeführt wird, geht der aktuelle Thread in den Ruhezustand, nicht der t-Thread. t.suspend() ist eine veraltete Methode. Die Verwendung von suspend() führt dazu, dass der Thread den Monitor des Objekts immer hält.

object.wait() versetzt den aktuellen Thread in einen „nicht ausführbaren“ Zustand. Der Unterschied zu sleep() besteht darin, dass wait eine Methode eines Objekts und nicht eines Threads ist. Beim Aufruf von object.wait () muss der Thread zuerst die Objektsperre dieses Objekts erwerben. Der aktuelle Thread muss die Synchronisierung für das Sperrobjekt aufrechterhalten und den aktuellen Thread zur Warteschlange hinzufügen.

Anschließend kann ein anderer Thread dieselbe Objektsperre synchronisieren, um object.notify() aufzurufen, was den ursprünglich wartenden Thread aufweckt und dann die Sperre aufhebt. Im Grunde ähnelt wait()/notify() Sleep()/interrupt(), außer dass ersteres die Objektsperre erwerben muss.

Was ist Thread-Hunger und was ist Livelock?

Wenn alle Threads blockiert sind oder nicht verarbeitet werden können, weil die erforderlichen Ressourcen ungültig sind, gibt es keine nicht blockierenden Threads, um die Ressourcen verfügbar zu machen. Thread-Livelock in der Java-API kann in den folgenden Situationen auftreten:

1, wenn alle Threads Object.wait(0) im Programm und die Wartemethode mit Parameter 0 ausführen. Das Programm führt eine Live-Sperre durch, bis ein Thread Object.notify() oder Object.notifyAll() für das entsprechende Objekt aufruft.

2, wenn alle Threads in einer Endlosschleife stecken bleiben.

Was ist die Java-Timer-Klasse? Wie erstelle ich eine Aufgabe mit einem bestimmten Zeitintervall?

java.util.Timer ist eine Toolklasse, mit der ein Thread so geplant werden kann, dass er zu einem bestimmten Zeitpunkt in der Zukunft ausgeführt wird. Mit der Timer-Klasse können einmalige oder periodische Aufgaben geplant werden.

java.util.TimerTask ist eine abstrakte Klasse, die die Runnable-Schnittstelle implementiert. Wir müssen diese Klasse erben, um unsere eigenen geplanten Aufgaben zu erstellen und Timer zum Planen ihrer Ausführung zu verwenden.

Was ist der Unterschied zwischen synchronisierten Sammlungen und gleichzeitigen Sammlungen in Java?

Sowohl synchronisierte Sammlungen als auch gleichzeitige Sammlungen bieten geeignete threadsichere Sammlungen für Multithreading und Parallelität, gleichzeitige Sammlungen sind jedoch skalierbarer.

Vor Java 1.5 konnten Programmierer nur synchronisierte Sammlungen verwenden, was bei gleichzeitiger Ausführung von Multithreads zu Konflikten führte und die Skalierbarkeit des Systems beeinträchtigte.

Java5 führte gleichzeitige Sammlungen wie ConcurrentHashMap ein, die nicht nur Thread-Sicherheit bieten, sondern auch die Skalierbarkeit mit modernen Technologien wie Sperrentrennung und interner Partitionierung verbessern.

Synchronisierte Methode oder synchronisierter Block, welche ist die bessere Wahl?

Ein synchronisierter Block ist die bessere Wahl, da er nicht das gesamte Objekt sperrt (natürlich können Sie auch festlegen, dass er das gesamte Objekt sperrt). Synchronisierte Methoden sperren das gesamte Objekt, auch wenn die Klasse mehrere unabhängige synchronisierte Blöcke enthält, was normalerweise dazu führt, dass sie nicht mehr ausgeführt werden und warten müssen, bis die Sperre für das Objekt erhalten wird.

Was ist ein Thread-Pool? Warum es verwenden?

Das Erstellen von Threads kostet teure Ressourcen und Zeit. Wenn Threads erst erstellt werden, nachdem eine Aufgabe eintrifft, wird die Antwortzeit länger und die Anzahl der Threads, die von einem Prozess erstellt werden können, ist begrenzt.

Um diese Probleme zu vermeiden, werden mehrere Threads erstellt, die beim Start des Programms auf die Verarbeitung reagieren. Sie werden Thread-Pools genannt, und die Threads darin werden Worker-Threads genannt.

Ab JDK1.5 stellt die Java-API das Executor-Framework bereit, damit Sie verschiedene Thread-Pools erstellen können. Beispielsweise verarbeitet ein einzelner Thread-Pool jeweils eine Aufgabe; eine feste Anzahl von Thread-Pools oder ein Cache-Thread-Pool (ein skalierbarer Thread-Pool, der für Programme mit vielen kurzlebigen Aufgaben geeignet ist).

Was ist der Unterschied zwischen invokeAndWait und invokeLater in Java?

Diese beiden Methoden werden von der Swing-API für Java-Entwickler bereitgestellt, um GUI-Komponenten aus dem aktuellen Thread statt aus dem Event-Dispatch-Thread zu aktualisieren. InvokeAndWait() aktualisiert GUI-Komponenten wie einen Fortschrittsbalken synchron. Sobald der Fortschritt aktualisiert ist, muss sich auch der Fortschrittsbalken entsprechend ändern.

Wenn der Fortschritt von mehreren Threads verfolgt wird, rufen Sie die Methode invokeAndWait() auf, um den Event-Dispatch-Thread aufzufordern, die Komponente entsprechend zu aktualisieren. Die Methode invokeLater() ruft die Update-Komponente asynchron auf.

Was ist eine Besetztschleife beim Multithreading?

Eine Besetztschleife liegt vor, wenn Programmierer im Gegensatz zur herkömmlichen Methode eine Schleife verwenden, um einen Thread warten zu lassen wait(), sleep() oder yield() geben beide die CPU-Steuerung auf, aber die Busy-Schleife gibt die CPU nicht auf, sie führt eine leere Schleife aus. Der Zweck besteht darin, den CPU-Cache zu schonen.

Auf einem Multi-Core-System läuft beim Aufwachen möglicherweise ein wartender Thread auf einem anderen Kern, wodurch der Cache neu erstellt wird. Es kann verwendet werden, um einen Neuaufbau des Caches zu vermeiden und die Wartezeit für den Neuaufbau zu verkürzen.

Das obige ist der detaillierte Inhalt vonFragen zum Java-Multithreading-Interview. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn