Da ich "In Java gelernte Entwurfsmuster (Multithread Edition)" gelesen habe, werde ich die wichtigsten Punkte aufzeichnen.
--Methode 1 Verwenden Sie die Klasse java.lang.Thread.
Das Verhalten des neu gestarteten Threads wird in der ** run ** -Methode der ** Thread ** -Klasse beschrieben. Durch Aufrufen der ** start ** -Methode der Thread-Klasse wird ein neuer Thread gestartet. Wenn Sie die Startmethode aufrufen, wird ein neuer Thread gestartet und die Ausführungsmethode aufgerufen.
public class Main {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
for (int i = 0; i < 100; i++) {
System.out.print("1");
}
}
public static class MyThread extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print("2");
}
}
}
}
Erstes Mal
Ausführungsergebnis
11111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211111111111111111111111111111111111111111111111111111111111111111111222222
Zweites Mal
Ausführungsergebnis
11111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
--Methode 2 Verwenden Sie die Runnbale-Schnittstelle
Starten Sie einen Thread mit einer Instanz einer Klasse, die die ** Runnable ** -Schnittstelle implementiert. Die ausführbare Schnittstelle wird wie folgt deklariert:
public interface Runnable {
public abstract void run();
}
Erstellen Sie eine Klasse, die die Runnbale-Schnittstelle implementiert, übergeben Sie die Instanz an den Thread-Konstruktor und rufen Sie die Startmethode auf.
public class Main {
public static void main(String[] args) {
Runnable myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
for (int i = 0; i < 100; i++) {
System.out.print("1");
}
}
public static class MyThread implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print("2");
}
}
}
}
Verwenden Sie Thread.sleep. Schließen Sie den Methodenaufruf ** sleep ** in try-catch ein. Die Sleep-Methode löst eine ** InterruptedException ** -Ausnahme aus.
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.print("1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
Das enttäuschende Thread-Verhalten, das durch die Konkurrenz (Race) zwischen Thread A und Thread B verursacht wird, wird als ** Data Race ** bezeichnet. Die Verkehrskontrolle ist erforderlich, um Datenspuren zu verhindern, die üblicherweise als ** exklusive Kontrolle ** bezeichnet werden. In Java wird das Schlüsselwort ** synchronisiert ** verwendet, wenn eine exklusive Steuerung von Threads durchgeführt wird. Wenn Sie eine Methode mit synchronisiertem Schlüsselwort deklarieren, wird die Methode in einem einzelnen Thread ausgeführt. Solche Methoden werden als ** synchronisierte Methode ** und ** synchronisierte Methode ** bezeichnet.
public class Bank {
private int money;
private String name;
public Bank(String name, int money) {
this.name = name;
this.money = money;
}
//Machen Sie eine Einzahlung
public synchronized void deposit(int m) { //Synchrone Methode
money += m;
}
//Herausziehen
public synchronized boolean withdraw(int m) { //Synchrone Methode
if (money >= m) {
money -= m;
return true;
} else {
return false;
}
}
public String getName() {
return name;
}
}
Wenn auch nur ein Thread eine ** Sperre ** hat, kann kein anderer Thread eintreten. Die Sperre wird aufgehoben, wenn der Thread, der die synchronisierte Methode ausgeführt hat, die Ausführung dieser Methode beendet hat. Wenn die Sperre aufgehoben wird, kann jeder der zuvor gesperrten und nicht eingegebenen Threads die Sperre übernehmen.
Für jede Instanz sind Sperren vorhanden. Das Ausführen der synchronisierten Methode einer Instanz bedeutet nicht, dass die synchronisierte Methode einer anderen Instanz nicht ausgeführt werden kann.
Mit der Thread.holdsLock-Methode können Sie überprüfen, ob der aktuelle Thread eine Sperre für ein Objekt aufweist.
Verwenden Sie den ** synchronisierten Block **, wenn einige der Methoden in einem einzelnen Thread anstelle der gesamten Methode funktionieren sollen.
synchronized (Formel) {
...
}
Die folgenden sind äquivalent
synchronized void method() {
...
}
void method() {
synchronized (this) {
...
}
}
Die folgenden sind äquivalent
class Something {
static synchronized void method() {
....
}
}
class Something {
static void method() {
synchronized (Something.class) {
....
}
}
}
Jede Instanz hat einen ** Gewichtssatz **. Ein Gewichtungssatz ist ein Satz von Threads, die die ** wait ** -Methode dieser Instanz ausführen und gestoppt werden. Es ist wie ein Thread-Warteraum für jede Instanz. Wenn der Thread die Wartemethode ausführt, pausiert er seine Operation und betritt einen Warteraum, der als Wartesatz bezeichnet wird. Der Thread wartet in seinem eingestellten Gewicht, bis eines der folgenden Ereignisse eintritt:
Zum Beispiel obj.wait(); Wenn die Anweisung ausgeführt wird, wird der aktuelle Thread angehalten und der Wartesatz der Instanz obj eingegeben. Dies wird gesagt, dass der Thread auf obj wartet. Der Thread muss eine Sperre haben, um die Wartemethode ausführen zu können.
Weight Set ist ein virtuelles Konzept. Es gibt keine Methode, um eine Liste der für eine Instanz gewichteten Threads abzurufen.
(In diesem Buch gibt es ein Diagramm, das dieses Konzept auf leicht verständliche Weise darstellt. Bitte beziehen Sie sich darauf.)
Verwenden Sie die ** notify ** -Methode, um einen der Threads im Gewichtssatz aus dem Gewichtssatz zu entfernen. Zum Beispiel obj.notify(); Wird von einem Thread ausgeführt. Dann wird ein Thread aus den Threads im Gewichtssatz von obj ausgewählt und dieser Thread wird aktiviert. Der aufgeweckte Faden verlässt das eingestellte Gewicht. Der Thread muss gesperrt sein, um die Benachrichtigungsmethode ausführen zu können. ** Ein von notify erzeugter Thread setzt die Ausführung nicht fort, sobald er benachrichtigt wird. ** Weil der benachrichtigte Thread zum Zeitpunkt der Benachrichtigung die Sperre hat. ** Wenn beim Ausführen der Benachrichtigungsmethode mehrere Threads im Wartesatz warten, wird der ausgewählte Thread in den Spezifikationen nicht angegeben. ** ** **
Verwenden Sie die notifyAll-Methode, um alle Threads im Gewichtssatz aus dem Gewichtssatz zu entfernen. Wie die wait-Methode und die norify-Methode kann die notifyAll-Methode nur von dem Thread aufgerufen werden, der über die Sperre der aufzurufenden Instanz verfügt. Wie bei notify wird der Thread, der herauskam, nicht sofort neu gestartet. Nachdem der Thread, der notifyAll ausgeführt hat, die Sperre aufgehoben hat, kann nur ein glücklicher Thread die Ausführung fortsetzen.
Eine Ausnahme ** java.lang.IllegalMonitorStateException ** wird ausgelöst, wenn ein Thread ohne Sperraufruf wartet, benachrichtigt, benachrichtigt.
Der Thread hat die folgenden Zustände.
--NEU: Status von Threads, die nicht gestartet wurden --RUNNABLE: Status der Threads, die auf Java Virtual Machines ausgeführt werden --TERMINATED: Status des terminierten Threads --WAITING: Der Status eines Threads, der auf unbestimmte Zeit darauf wartet, dass ein anderer Thread eine bestimmte Aktion ausführt. --TIMED_WAITING: Status des Threads, der darauf wartet, dass ein anderer Thread die Aktion für die angegebene Wartezeit ausführt --BLOCKED: Status der Threads, die blockiert sind und auf eine Monitorsperre warten
Diese Zustände können mit der getState-Methode der Thread-Klasse abgerufen werden.
Der Quellcode kann von der HP des Autors heruntergeladen werden. http://www.hyuki.com
Recommended Posts