Letzten Freitag und Wochenende habe ich eine Pause von meiner geschäftigen Arbeit gemacht und die Implementierung von Thread.interrupt und LockSupport nach Java 5 überprüft, während ich mir Java Cocurrent angesehen habe.
Lassen Sie mich vor der Einführung ein paar Fragen stellen.
Welche Beziehung besteht zwischen der Thread.interrupt()-Methode und InterruptedException? Wird die InterruptedException-Ausnahme durch einen Interrupt ausgelöst?
In welchem Zustand unterbricht Thread.interrupt() die Arbeit des Threads? LAUFEN oder BLOCKIEREN?
Muss bei der allgemeinen Thread-Programmierung auf Interrupts geachtet werden? Wie gehe ich generell damit um? Wofür kann es verwendet werden?
Was ist der Unterschied zwischen LockSupport.park() und unpark() sowie object.wait() und notify()?
Wozu dient das von LockSupport.park (Objektblocker) übergebene Blockerobjekt?
Kann LockSupport auf Thread.interrupt()-Ereignisse reagieren? Wird eine InterruptedException ausgelöst?
Gibt es eine entsprechende Rückruffunktion für die Thread.interrupt()-Verarbeitung? So etwas wie ein Hook-Call?
Wenn Sie alles klar beantworten können, bedeutet das, dass Sie Thread.interrupt bereits vollständig verstanden haben und nicht weiter lesen müssen.
Wenn Sie sich immer noch nicht sicher sind, klären wir es gemeinsam mit diesen Fragen.
Mehrere Methoden zur Behandlung des Thread-Interrupts:
public void interrupt(): Thread-Interrupt-Ereignis ausführen
public boolean isInterrupted() : Überprüfen Sie, ob der aktuelle Thread unterbrochen ist
public static boolean interrupted(): Überprüfen Sie, ob der aktuelle Thread unterbrochen ist, und setzen Sie die Interrupt-Informationen zurück. Ähnlich wie resetAndGet()
verstehen:
1. Jeder Thread verfügt über ein Interrupt-Status-Flag, das anzeigt, ob sich der aktuelle Thread in einem unterbrochenen Zustand befindet.
2. Im Allgemeinen gibt es zwei Verarbeitungsmethoden, wenn Thread.interrupt () aufgerufen wird, wenn ein Blockstatus mit niedriger Priorität auftritt, z. B. object.wait (), object.sleep (), object.join (). Es löst sofort eine Entsperrung aus, um die Blockierung aufzuheben und eine InterruptedException auszulösen.
In anderen Fällen aktualisiert Thread.interrupt() nur das Statusflag. Anschließend überprüft Ihr Arbeitsthread Thread.isInterrrupted() und kann die entsprechende Verarbeitung durchführen, z. B. das Auslösen einer InterruptedException oder das Löschen des Status, das Abbrechen der Aufgabe usw.
Beschrieben im Interrupt-Javadoc:
Best Practices
Es gibt einen Artikel über IBM, der ziemlich gut ist. Java-Theorie und -Praxis: Umgang mit InterruptedException, in dem mehrere Best Practices für die Interrupt-Behandlung erwähnt werden.
Interrupts nicht schlucken (Interrupt nicht essen, es gibt im Allgemeinen zwei Arten der Verarbeitung: weiterhin InterruptedException auslösen. Die andere besteht darin, weiterhin das Ausnahmeflag Thread.interupt () zu setzen, damit die höhere Ebene entsprechend damit umgehen kann.
Kopieren Sie den Codecode wie folgt:
Die öffentliche Klasse TaskRunner implementiert Runnable {
private BlockingQueue<Task>-Warteschlange;
public TaskRunner(BlockingQueue<Task> queue) {
this.queue = Warteschlange;
}
public void run() {
versuchen {
while (wahr) {
Aufgabe task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
Catch (InterruptedException e) {
// Den unterbrochenen Status wiederherstellen
Thread.currentThread().interrupt();
}
}
}
Kopieren Sie den Codecode wie folgt:
Die öffentliche Klasse TaskRunner implementiert Runnable {
private BlockingQueue<Task>-Warteschlange;
public TaskRunner(BlockingQueue<Task> queue) {
this.queue = Warteschlange;
}
public void run() {
versuchen {
while (wahr) {
Aufgabe task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
Catch (InterruptedException e) {
// Den unterbrochenen Status wiederherstellen
Thread.currentThread().interrupt();
}
}
}
Implementieren abbrechbarer Aufgaben mit Interrupt (verwenden Sie Thread.interrupt(), um abbrechbare Aufgaben zu entwerfen und zu unterstützen)
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse PrimeProducer erweitert Thread {
private finale BlockingQueue<BigInteger>-Warteschlange;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = Warteschlange;
}
public void run() {
versuchen {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} Catch (InterruptedException verbraucht) {
/* Thread beenden lassen */
}
}
public void cancel() { interrupt( } // Einen Interrupt einleiten
}<SPAN style="WHITE-SPACE: normal"> </SPAN>
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse PrimeProducer erweitert Thread {
private finale BlockingQueue<BigInteger>-Warteschlange;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = Warteschlange;
}
public void run() {
versuchen {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} Catch (InterruptedException verbraucht) {
/* Thread beenden lassen */
}
}
public void cancel() { interrupt( } // Einen Interrupt einleiten
}<SPAN style="WHITE-SPACE: normal"> </SPAN>
Interrupt-Verarbeitungsereignis registrieren (abnormale Verwendung)
Im Allgemeinen sind normale Aufgaben für den Abbruch ausgelegt und verwenden alle aktive Abfragen, um Thread.isInterrupt () zu überprüfen. Dies hat einen gewissen Grad an Einbettung in das Unternehmen selbst und es gibt auch eine Verzögerung Prüfpunkt (wer weiß, wann der nächste Prüfpunkt ist? Insbesondere beim Durchführen eines socket.read bin ich auf ein HttpClient-Timeout-Problem gestoßen).
Werfen wir einen Blick darauf. Die Implementierung des aktiven Auslösens von InterruptedException basiert auf dem Design von InterruptibleChannel, was ziemlich clever ist.
Kopieren Sie den Codecode wie folgt:
interface InterruptAble { // Definieren Sie eine unterbrechbare Schnittstelle
public void interrupt() löst eine InterruptedException aus;
}
Die abstrakte Klasse InterruptSupport implementiert InterruptAble {
privater flüchtiger boolescher Wert unterbrochen = falsch;
private Interruptible interruptor = new Interruptible() {
public void interrupt() {
unterbrochen = wahr;
InterruptSupport.this.interrupt(); // Position 3
}
};
public final booleanexecute() wirft InterruptedException {
versuchen {
blockiertOn(interruptor); // Position 1
if (Thread.currentThread().isInterrupted()) { // Sofort unterbrochen
unterbrecher.interrupt();
}
//Geschäftscode ausführen
Geschäft();
} Endlich {
blockiertOn(null); // Position 2
}
Rückkehr unterbrochen;
}
public abstract void business() ;
öffentlicher abstrakter void interrupt();
// -- sun.misc.SharedSecrets --
static void blockiertOn(Interruptible intr) { // package-private
sun.misc.SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(), intr);
}
}
Kopieren Sie den Codecode wie folgt:
interface InterruptAble { // Definieren Sie eine unterbrechbare Schnittstelle
public void interrupt() löst eine InterruptedException aus;
}
Die abstrakte Klasse InterruptSupport implementiert InterruptAble {
privater flüchtiger boolescher Wert unterbrochen = falsch;
private Interruptible interruptor = new Interruptible() {
public void interrupt() {
unterbrochen = wahr;
InterruptSupport.this.interrupt(); // Position 3
}
};
public final booleanexecute() wirft InterruptedException {
versuchen {
blockiertOn(interruptor); // Position 1
if (Thread.currentThread().isInterrupted()) { // Sofort unterbrochen
unterbrecher.interrupt();
}
//Geschäftscode ausführen
Geschäft();
} Endlich {
blockiertOn(null); // Position 2
}
Rückkehr unterbrochen;
}
public abstract void business() ;
öffentlicher abstrakter void interrupt();
// -- sun.misc.SharedSecrets --
static void blockiertOn(Interruptible intr) { // package-private
sun.misc.SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(), intr);
}
}
Codebeschreibung, ein paar Tricks:
Position 1: Verwenden Sie die von Sun bereitgestellte BlockedOn-Methode, um den entsprechenden Hook für die Verarbeitung unterbrechbarer Ereignisse an den angegebenen Thread zu binden.
Position 2: Nachdem Sie den Code ausgeführt haben, löschen Sie den Haken. Vermeiden Sie die Auswirkungen auf das nächste Thread-Verarbeitungsereignis, wenn Sie den Verbindungspool verwenden.
Position 3: Definiert die Verarbeitungsmethode des Interruptible-Ereignis-Hooks und ruft die InterruptSupport.this.interrupt()-Methode zurück. Unterklassen können ihre eigene Geschäftslogik integrieren und implementieren, z. B. das Schließen des Sock-Streams usw.
verwenden:
Kopieren Sie den Codecode wie folgt:
Klasse InterruptRead erweitert InterruptSupport {
privater FileInputStream in;
@Override
public void business() {
Datei file = new File("/dev/urandom"); // Das schwarze Loch von Linux lesen, nie zu Ende lesen
versuchen {
in = new FileInputStream(file);
byte[] bytes = neues byte[1024];
while (in.read(bytes, 0, 1024) > 0) {
// Thread.sleep(100);
// if (Thread.interrupted()) {// Vorherige Interrupt-Prüfmethode
// throw new InterruptedException("");
// }
}
} Catch (Ausnahme e) {
throw new RuntimeException(e);
}
}
public FileInputStream getIn() {
zurückkehren;
}
@Override
public void interrupt() {
versuchen {
in.getChannel().close();
} Catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) löst eine Ausnahme aus {
letzter InterruptRead-Test = new InterruptRead();
Thread t = neuer Thread() {
@Override
public void run() {
langer Start = System.currentTimeMillis();
versuchen {
System.out.println("InterruptRead start!");
test.execute();
} Catch (InterruptedException e) {
System.out.println("InterruptRead end! cost time : " + (System.currentTimeMillis() - start));
e.printStackTrace();
}
}
};
t.start();
// Read zunächst 3 Sekunden lang ausführen lassen
Thread.sleep(3000);
// Einen Interrupt ausgeben
t.interrupt();
}
Kopieren Sie den Codecode wie folgt:
Klasse InterruptRead erweitert InterruptSupport {
privater FileInputStream in;
@Override
public void business() {
Datei file = new File("/dev/urandom"); // Das schwarze Loch von Linux lesen, nie zu Ende lesen
versuchen {
in = new FileInputStream(file);
byte[] bytes = neues byte[1024];
while (in.read(bytes, 0, 1024) > 0) {
// Thread.sleep(100);
// if (Thread.interrupted()) {// Vorherige Interrupt-Prüfmethode
// throw new InterruptedException("");
// }
}
} Catch (Ausnahme e) {
throw new RuntimeException(e);
}
}
public FileInputStream getIn() {
zurückkehren;
}
@Override
public void interrupt() {
versuchen {
in.getChannel().close();
} Catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) löst eine Ausnahme aus {
letzter InterruptRead-Test = new InterruptRead();
Thread t = neuer Thread() {
@Override
public void run() {
langer Start = System.currentTimeMillis();
versuchen {
System.out.println("InterruptRead start!");
test.execute();
} Catch (InterruptedException e) {
System.out.println("InterruptRead end! cost time : " + (System.currentTimeMillis() - start));
e.printStackTrace();
}
}
};
t.start();
// Read zunächst 3 Sekunden lang ausführen lassen
Thread.sleep(3000);
// Einen Interrupt ausgeben
t.interrupt();
}
Einführung in den JDK-Quellcode:
1. Der von Sun bereitgestellte Hook kann den relevanten Code des Systems anzeigen, Zeile: 1125
Kopieren Sie den Codecode wie folgt:
sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){
public sun.reflect.ConstantPool getConstantPool(Class klass) {
return klass.getConstantPool();
}
public void setAnnotationType(Class klass, AnnotationType type) {
klass.setAnnotationType(type);
}
public AnnotationType getAnnotationType(Class klass) {
return klass.getAnnotationType();
}
public <E erweitert Enum<E>>
E[] getEnumConstantsShared(Class<E> klass) {
return klass.getEnumConstantsShared();
}
public void blockiertOn(Thread t, Interruptible b) {
t.blockedOn(b);
}
});
Kopieren Sie den Codecode wie folgt:
sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){
public sun.reflect.ConstantPool getConstantPool(Class klass) {
return klass.getConstantPool();
}
public void setAnnotationType(Class klass, AnnotationType type) {
klass.setAnnotationType(type);
}
public AnnotationType getAnnotationType(Class klass) {
return klass.getAnnotationType();
}
public <E erweitert Enum<E>>
E[] getEnumConstantsShared(Class<E> klass) {
return klass.getEnumConstantsShared();
}
public void blockiertOn(Thread t, Interruptible b) {
t.blockedOn(b);
}
});
2. Thread.interrupt()
Kopieren Sie den Codecode wie folgt:
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronisiert (blockerLock) {
Unterbrechbar b = Blocker;
if (b != null) {
interrupt0(); // Nur um das Interrupt-Flag zu setzen
b.interrupt(); //Callback-Hook
zurückkehren;
}
}
interrupt0();
}
Kopieren Sie den Codecode wie folgt:
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronisiert (blockerLock) {
Unterbrechbar b = Blocker;
if (b != null) {
interrupt0(); // Nur um das Interrupt-Flag zu setzen
b.interrupt(); //Callback-Hook
zurückkehren;
}
}
unterbrechen0();
}
Weitere Informationen zur Verwendung von Thread.stop, Suspend, Resume und Interrupt finden Sie in der Dokumentation von Sun, z. B. http://download.oracle.com/javase/6/docs/technotes/guides/concurrency /threadPrimitiveDeprecation .html
Lassen Sie uns abschließend einige der vorherigen Fragen beantworten:
Frage 1: Welche Beziehung besteht zwischen der Thread.interrupt()-Methode und InterruptedException? Wird die InterruptedException-Ausnahme durch einen Interrupt ausgelöst?
Antwort: Thread.interrupt() löst aktiv eine InterruptedException nur in Object.wait(), .Object.join() und Object.sleep() aus. In anderen Blöcken ist es üblich, einfach die Flag-Informationen des Threads festzulegen, und das Programm muss sie selbst verarbeiten.
Kopieren Sie den Codecode wie folgt:
if (Thread.interrupted()) // Löscht den unterbrochenen Status!
throw new InterruptedException();
Kopieren Sie den Codecode wie folgt:
if (Thread.interrupted()) // Löscht den unterbrochenen Status!
throw new InterruptedException();
Frage 2: In welchem Zustand unterbricht Thread.interrupt() die Arbeit des Threads? LAUFEN oder BLOCKIEREN?
Antwort: Der Zweck des Thread.interrupt-Designs besteht hauptsächlich darin, Threads im Blockzustand zu verarbeiten, z. B. im Wait()- und Sleep()-Zustand. Das Abbrechen von Aufgaben kann jedoch während des Programmentwurfs unterstützt werden, und der RUNNING-Status kann ebenfalls unterstützt werden. Zum Beispiel Object.join() und einige Nio-Kanaldesigns, die Interrupt unterstützen.
Frage 3: Muss bei der allgemeinen Thread-Programmierung auf Interrupts geachtet werden? Wie gehe ich generell damit um? Wofür kann es verwendet werden?
Antwort: Interrupt-Nutzung: Blockierung des Vorgangs, unterstützt das Abbrechen von Aufgaben, Datenbereinigung usw.
Frage 4: Was ist der Unterschied zwischen LockSupport.park() und unpark() und object.wait() und notify()?
Antwort:
1. Die Themen sind unterschiedlich. LockSuport führt hauptsächlich die Blockierungsverarbeitung für Threads durch. Es kann das Zielobjekt der Blockierungswarteschlange angeben und einen bestimmten Thread angeben, der jedes Mal aktiviert werden soll. Object.wait() nimmt das Objekt als Dimension, blockiert den aktuellen Thread und weckt einen einzelnen (zufälligen) oder alle Threads auf.
2. Die Implementierungsmechanismen sind unterschiedlich. Obwohl LockSuport das Objektobjekt des Monitors angeben kann, überschneiden sich die Blockierungswarteschlangen von LockSuport und object.wait() nicht. Sie können sich das Testbeispiel ansehen. object.notifyAll() kann den blockierenden Thread von LockSupport nicht aktivieren.
Frage 5: Wozu dient das von LockSupport.park (Objektblocker) übergebene Blockerobjekt?
Antwort: Der entsprechende Blocker wird in einem parkBlocker-Attribut von Thread aufgezeichnet. Es ist sehr praktisch, bestimmte blockierende Objekte über den Befehl jstack zu überwachen.
Kopieren Sie den Codecode wie folgt:
öffentlicher statischer leerer Park (Objektblocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker); //Legen Sie den Wert der Thread.parkBlocker-Eigenschaft fest
unsicher.park(false, 0L);
setBlocker(t, null); // Wert der Thread.parkBlocker-Eigenschaft löschen
}
Kopieren Sie den Codecode wie folgt:
öffentlicher statischer leerer Park (Objektblocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker); //Legen Sie den Wert der Thread.parkBlocker-Eigenschaft fest
unsicher.park(false, 0L);
setBlocker(t, null); // Wert der Thread.parkBlocker-Eigenschaft löschen
}
Die spezifische Javadoc-Beschreibung von LockSupport ist ebenfalls relativ klar. Sie können sie unten lesen:
Frage 6: Kann LockSupport auf Thread.interrupt()-Ereignisse reagieren? Wird eine InterruptedException ausgelöst?
Antwort: Es kann auf Interrupt-Ereignisse reagieren, löst jedoch keine InterruptedException aus. Sehen Sie sich zur Unterstützung von LockSupport für Thread.interrupte auch die Beschreibung in Javadoc an:
Zugehöriger Testcode
Kopieren Sie den Codecode wie folgt:
Paket com.agapple.cocurrent;
java.io.File importieren;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
öffentliche Klasse LockSupportTest {
privater statischer LockSupportTest-Blocker = new LockSupportTest();
public static void main(String args[]) löst eine Ausnahme aus {
lockSupportTest();
parkTest();
interruptParkTest();
interruptSleepTest();
interruptWaitTest();
}
/**
* Versuchen Sie nach dem LockSupport.park-Objekt, das Thread.blocker-Objekt abzurufen und dessen einzelne Aktivierung aufzurufen
*
* @throwsException
*/
private static void lockSupportTest() löst eine Ausnahme aus {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() löst eine Ausnahme aus {
// Versuchen Sie, 5 Sekunden lang zu schlafen
System.out.println("blocker");
LockSupport.park(blocker);
System.out.println("Jetzt aufwachen!");
}
@Override
öffentlicher String getName() {
return „lockSupportTest“;
}
});
t.start(); // Lesethread starten
Thread.sleep(150);
synchronisiert (Blocker) {
Feld field = Thread.class.getDeclaredField("parkBlocker");
field.setAccessible(true);
Objekt fBlocker = field.get(t);
System.out.println(blocker == fBlocker);
Thread.sleep(100);
System.out.println("notifyAll");
blocker.notifyAll();
}
}
/**
* Wenn Sie versuchen, ein object.wait() zu unterbrechen, wird die entsprechende InterruptedException geworfen.
*
* @throws InterruptedException
*/
private static void interruptWaitTest() löst InterruptedException {
final Object obj = new Object();
Thread t = doTest(new TestCallBack() {
@Override
public void callback() löst eine Ausnahme aus {
// Versuchen Sie, 5 Sekunden lang zu schlafen
obj.wait();
System.out.println("Jetzt aufwachen!");
}
@Override
öffentlicher String getName() {
return „interruptWaitTest“;
}
});
t.start(); // Lesethread starten
Thread.sleep(2000);
t.interrupt(); // Prüfen, ob beim Parken auf den Interrupt reagiert wird
}
/**
* Wenn Sie versuchen, einen Thread.sleep() zu unterbrechen, wird die entsprechende InterruptedException geworfen.
*
* @throws InterruptedException
*/
private static void interruptSleepTest() löst InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() löst eine Ausnahme aus {
// Versuchen Sie, 5 Sekunden lang zu schlafen
Thread.sleep(5000);
System.out.println("Jetzt aufwachen!");
}
@Override
öffentlicher String getName() {
return „interruptSleepTest“;
}
});
t.start(); // Lesethread starten
Thread.sleep(2000);
t.interrupt(); // Prüfen, ob beim Parken auf den Interrupt reagiert wird
}
/**
* Versuchen Sie, einen LockSupport.park() zu unterbrechen. Es erfolgt eine Antwort, aber es wird keine InterruptedException-Ausnahme ausgelöst
*
* @throws InterruptedException
*/
private static void interruptParkTest() löst InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() {
//Versuchen Sie, Ihren eigenen Thread zu parken
LockSupport.parkNanos(blocker, TimeUnit.SECONDS.toNanos(5));
System.out.println("Jetzt aufwachen!");
}
@Override
öffentlicher String getName() {
return „interruptParkTest“;
}
});
t.start(); // Lesethread starten
Thread.sleep(2000);
t.interrupt(); // Prüfen, ob beim Parken auf den Interrupt reagiert wird
}
/**
* Versuchen Sie, einen LockSupport.unPark() zu unterbrechen, es erfolgt eine Antwort
*
* @throws InterruptedException
*/
private static void parkTest() löst InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() {
//Versuchen Sie, Ihren eigenen Thread zu parken
LockSupport.park(blocker);
System.out.println("Jetzt aufwachen!");
}
@Override
öffentlicher String getName() {
return „parkTest“;
}
});
t.start(); // Lesethread starten
Thread.sleep(2000);
LockSupport.unpark(t);
t.interrupt();
}
öffentlicher statischer Thread doTest(letzter TestCallBack-Aufruf) {
return new Thread() {
@Override
public void run() {
Datei file = new File("/dev/urandom"); // Linux Black Hole lesen
versuchen {
FileInputStream in = new FileInputStream(file);
byte[] bytes = neues byte[1024];
while (in.read(bytes, 0, 1024) > 0) {
if (Thread.interrupted()) {
throw new InterruptedException("");
}
System.out.println(bytes[0]);
Thread.sleep(100);
langer Start = System.currentTimeMillis();
call.callback();
System.out.println(call.getName() + „Callback-Endkosten:“
+ (System.currentTimeMillis() - start));
}
} Catch (Ausnahme e) {
e.printStackTrace();
}
}
};
}
}
Schnittstelle TestCallBack {
public void callback() löst eine Ausnahme aus;
öffentlicher String getName();
}
Kopieren Sie den Codecode wie folgt:
Paket com.agapple.cocurrent;
java.io.File importieren;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
öffentliche Klasse LockSupportTest {
privater statischer LockSupportTest-Blocker = new LockSupportTest();
public static void main(String args[]) löst eine Ausnahme aus {
lockSupportTest();
parkTest();
interruptParkTest();
interruptSleepTest();
interruptWaitTest();
}
/**
* Versuchen Sie nach dem LockSupport.park-Objekt, das Thread.blocker-Objekt abzurufen und dessen einzelne Aktivierung aufzurufen
*
* @throwsException
*/
private static void lockSupportTest() löst eine Ausnahme aus {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() löst eine Ausnahme aus {
// Versuchen Sie, 5 Sekunden lang zu schlafen
System.out.println("blocker");
LockSupport.park(blocker);
System.out.println("Jetzt aufwachen!");
}
@Override
öffentlicher String getName() {
return „lockSupportTest“;
}
});
t.start(); // Lesethread starten
Thread.sleep(150);
synchronisiert (Blocker) {
Feld field = Thread.class.getDeclaredField("parkBlocker");
field.setAccessible(true);
Objekt fBlocker = field.get(t);
System.out.println(blocker == fBlocker);
Thread.sleep(100);
System.out.println("notifyAll");
blocker.notifyAll();
}
}
/**
* Wenn Sie versuchen, ein object.wait() zu unterbrechen, wird die entsprechende InterruptedException geworfen.
*
* @throws InterruptedException
*/
private static void interruptWaitTest() löst InterruptedException {
final Object obj = new Object();
Thread t = doTest(new TestCallBack() {
@Override
public void callback() löst eine Ausnahme aus {
// Versuchen Sie, 5 Sekunden lang zu schlafen
obj.wait();
System.out.println("Jetzt aufwachen!");
}
@Override
öffentlicher String getName() {
return „interruptWaitTest“;
}
});
t.start(); // Lesethread starten
Thread.sleep(2000);
t.interrupt(); // Prüfen, ob beim Parken auf den Interrupt reagiert wird
}
/**
* Wenn Sie versuchen, einen Thread.sleep() zu unterbrechen, wird die entsprechende InterruptedException geworfen.
*
* @throws InterruptedException
*/
private static void interruptSleepTest() löst InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() löst eine Ausnahme aus {
// Versuchen Sie, 5 Sekunden lang zu schlafen
Thread.sleep(5000);
System.out.println("Jetzt aufwachen!");
}
@Override
öffentlicher String getName() {
return „interruptSleepTest“;
}
});
t.start(); // Lesethread starten
Thread.sleep(2000);
t.interrupt(); // Prüfen, ob beim Parken auf den Interrupt reagiert wird
}
/**
* Versuchen Sie, einen LockSupport.park() zu unterbrechen. Es erfolgt eine Antwort, aber es wird keine InterruptedException-Ausnahme ausgelöst
*
* @throws InterruptedException
*/
private static void interruptParkTest() löst InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() {
//Versuchen Sie, Ihren eigenen Thread zu parken
LockSupport.parkNanos(blocker, TimeUnit.SECONDS.toNanos(5));
System.out.println("Jetzt aufwachen!");
}
@Override
öffentlicher String getName() {
return „interruptParkTest“;
}
});
t.start(); // Lesethread starten
Thread.sleep(2000);
t.interrupt(); // Prüfen, ob beim Parken auf den Interrupt reagiert wird
}
/**
* Versuchen Sie, einen LockSupport.unPark() zu unterbrechen, es erfolgt eine Antwort
*
* @throws InterruptedException
*/
private static void parkTest() löst InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() {
//Versuchen Sie, Ihren eigenen Thread zu parken
LockSupport.park(blocker);
System.out.println("Jetzt aufwachen!");
}
@Override
öffentlicher String getName() {
return „parkTest“;
}
});
t.start(); // Lesethread starten
Thread.sleep(2000);
LockSupport.unpark(t);
t.interrupt();
}
öffentlicher statischer Thread doTest(finaler TestCallBack-Aufruf) {
return new Thread() {
@Override
public void run() {
Datei file = new File("/dev/urandom"); // Linux Black Hole lesen
versuchen {
FileInputStream in = new FileInputStream(file);
byte[] bytes = neues byte[1024];
while (in.read(bytes, 0, 1024) > 0) {
if (Thread.interrupted()) {
throw new InterruptedException("");
}
System.out.println(bytes[0]);
Thread.sleep(100);
langer Start = System.currentTimeMillis();
call.callback();
System.out.println(call.getName() + „Callback-Endkosten:“
+ (System.currentTimeMillis() - start));
}
} Catch (Ausnahme e) {
e.printStackTrace();
}
}
};
}
}
Schnittstelle TestCallBack {
public void callback() löst eine Ausnahme aus;
öffentlicher String getName();
}
Schließlich stellte ich fest, dass der Artikel immer länger wurde, also habe ich ihn einfach im Forum gepostet, damit alle ihn gemeinsam diskutieren konnten. Schließlich beschrieb der Artikel nur einige Dinge auf Nutzungsebene und stellte den Thread aus dem Betrieb nicht vor Zu einigen Mechanismen können Daniumen, die mit diesem Bereich vertraut sind, auch ihre Meinung äußern.