1. Erstellen Sie einen Thread
Es gibt zwei Möglichkeiten, Threads in Java zu erstellen: mit der Thread-Klasse und mit der Runnable-Schnittstelle. Wenn Sie die Runnable-Schnittstelle verwenden, müssen Sie eine Thread-Instanz erstellen. Unabhängig davon, ob Sie einen Thread über die Thread-Klasse oder die Runnable-Schnittstelle erstellen, müssen Sie daher eine Instanz der Thread-Klasse oder ihrer Unterklasse erstellen. Thread-Konstruktor:
Methode 1: Erben Sie die Thread-Klasse und überschreiben Sie die Ausführungsmethode
}
}
Klassendemo erweitert Thread{
public void run(){
for(int i=0;i<60;i++){
System.out.println(Thread.currentThread().getName()+i);
}
}
}
So wie Menschen geboren, alt, krank und sterben, müssen auch Threads vier verschiedene Zustände durchlaufen: Starten (Warten), Laufen, Hängen und Stoppen. Diese vier Zustände können durch Methoden in der Thread-Klasse gesteuert werden. Die Methoden, die sich auf diese vier Zustände in der Thread-Klasse beziehen, sind unten aufgeführt.
Der Thread führt den Code in der Ausführungsmethode nicht unmittelbar nach seiner Einrichtung aus, sondern befindet sich im Wartezustand. Wenn sich der Thread im Wartezustand befindet, können Sie über die Methoden der Thread-Klasse verschiedene Attribute des Threads festlegen, z. B. die Priorität des Threads (setPriority), den Thread-Namen (setName) und den Thread-Typ (setDaemon).
Wenn die Startmethode aufgerufen wird, beginnt der Thread mit der Ausführung des Codes in der Run-Methode. Der Thread wechselt in den laufenden Zustand. Sie können die isAlive-Methode der Thread-Klasse verwenden, um festzustellen, ob der Thread ausgeführt wird. Wenn sich der Thread im laufenden Zustand befindet, gibt isAlive „true“ zurück. Wenn isAlive „false“ zurückgibt, befindet sich der Thread möglicherweise im Wartezustand oder im gestoppten Zustand. Der folgende Code demonstriert den Wechsel zwischen den drei Zuständen Thread-Erstellung, Ausführung und Stopp und gibt den entsprechenden isAlive-Rückgabewert aus.
Sobald der Thread mit der Ausführung der Ausführungsmethode beginnt, wird er erst beendet, wenn die Ausführungsmethode abgeschlossen ist. Während der Thread-Ausführung gibt es jedoch zwei Methoden, mit denen die Thread-Ausführung vorübergehend gestoppt werden kann. Diese beiden Methoden sind Suspend und Sleep. Nachdem Sie einen Thread mit Suspend angehalten haben, können Sie ihn über die Resume-Methode aktivieren. Nachdem der Thread mit Sleep in den Ruhezustand versetzt wurde, kann er sich erst nach der festgelegten Zeit im Bereitschaftszustand befinden (nachdem der Thread-Ruhezustand endet, wird der Thread möglicherweise nicht sofort ausgeführt, sondern wechselt nur in den Bereitschaftszustand und wartet auf die Planung durch das System). .
Bei der Anwendung der Schlafmethode sind zwei Punkte zu beachten:
1. Die Schlafmethode hat zwei überladene Formen. Eine der überladenen Formen kann nicht nur Millisekunden, sondern auch Nanosekunden festlegen (1.000.000 Nanosekunden entsprechen 1 Millisekunde). Allerdings ist die Java Virtual Machine auf den meisten Betriebssystemplattformen nicht auf Nanosekunden genau. Wenn daher Nanosekunden für den Ruhezustand eingestellt sind, verwendet die Java Virtual Machine die Millisekunde, die diesem Wert am nächsten kommt.
2. Throws oder try{...}catch{...} müssen verwendet werden, wenn die Sleep-Methode verwendet wird. Da die run-Methode keine Würfe verwenden kann, können Sie nur try{...}catch{...} verwenden. Wenn der Thread schläft und die Interrupt-Methode zum Unterbrechen des Threads verwendet wird, löst Sleep eine InterruptedException aus. Die Schlafmethode ist wie folgt definiert:
Es gibt drei Möglichkeiten, einen Thread zu beenden.
1. Verwenden Sie das Exit-Flag, um den Thread normal zu beenden, dh der Thread wird beendet, wenn die Ausführungsmethode abgeschlossen ist.
2. Verwenden Sie die Stopp-Methode, um den Thread zwangsweise zu beenden (diese Methode wird nicht empfohlen, da Stoppen ebenso wie Suspend und Resume zu unvorhersehbaren Ergebnissen führen kann).
3. Verwenden Sie die Interrupt-Methode, um den Thread zu unterbrechen.
1. Beenden Sie den Thread mit dem Exit-Flag
Wenn die run-Methode ausgeführt wird, wird der Thread beendet. Aber manchmal endet die Ausführungsmethode nie. Beispielsweise werden Threads in Serverprogrammen verwendet, um Client-Anfragen oder andere Aufgaben zu überwachen, die eine zyklische Verarbeitung erfordern. In diesem Fall werden diese Aufgaben normalerweise in einer Schleife, beispielsweise einer While-Schleife, platziert. Wenn Sie möchten, dass die Schleife ewig läuft, können Sie while(true){...} verwenden, um damit umzugehen. Wenn Sie jedoch möchten, dass die While-Schleife unter einer bestimmten Bedingung beendet wird, besteht der direkteste Weg darin, ein boolesches Flag zu setzen und dieses Flag auf true oder false zu setzen, um zu steuern, ob die While-Schleife beendet wird. Nachfolgend finden Sie ein Beispiel für das Beenden eines Threads mithilfe des Exit-Flags.
Die Funktion der Join-Methode besteht darin, asynchrone Ausführungsthreads zu synchroner Ausführung zu machen. Das heißt, wenn die Startmethode der Thread-Instanz aufgerufen wird, kehrt diese Methode sofort zurück. Wenn Sie nach dem Aufruf der Startmethode einen von diesem Thread berechneten Wert verwenden müssen, müssen Sie die Join-Methode verwenden. Wenn Sie die Join-Methode nicht verwenden, gibt es keine Garantie dafür, dass der Thread ausgeführt wird, wenn eine Anweisung nach der Startmethode ausgeführt wird. Nach Verwendung der Join-Methode setzt das Programm die Ausführung erst fort, wenn dieser Thread beendet wird. Der folgende Code demonstriert die Verwendung von Join.
3. Multithread-Sicherheitsprobleme
Ursache des Problems: Wenn mehrere Anweisungen auf demselben Thread ausgeführt werden und Daten gemeinsam nutzen, führt ein Thread nur einen Teil der mehreren Anweisungen aus. Bevor die Ausführung abgeschlossen ist, beteiligt sich ein anderer Thread an der Ausführung, was zu Fehlern bei den gemeinsamen Daten führt.
Lösung: Bei mehreren Anweisungen, die gemeinsam genutzte Daten verarbeiten, kann nur ein Thread ausgeführt werden. Während des Ausführungsprozesses werden andere Threads nicht ausgeführt.
Synchroner Codeblock:
}
}
}
}
public void run(){
while(true){
saleTicket();
}
}
}
Kommunikation zwischen Threads
x=(x+1)%2;
}
}
}).Start();
neuer Thread(new Runnable(){
public void run(){
while(true){
p.get();
}
}
}).Start();
}
}
/*
Zhang San....Männlich Zhang San....Männlich
lili....nv
lili....männlich Zhang San....nv
Lili....männlich
*/
}
}
}).Start();
neuer Thread(new Runnable(){
public void run(){
while(true){
synchronisiert (p) {
p.get();
}
}
}
}).Start();
}
}
/*
lili....nv
lili....nv
lili....nv
lili....nv
lili....nv
lili....nv
Zhang San....Männlich Zhang San....Männlich Zhang San....Männlich Zhang San....Männlich
*/
}
}
}).Start();
neuer Thread(new Runnable(){
public void run(){
while(true){
synchronisiert (p) {
if(!flags)
versuchen {
p.wait();
} Catch (InterruptedException e) {
// TODO Automatisch generierter Catch-Block
e.printStackTrace();
};
p.get();
Flags =false;
p.notifyAll();
}
}
}
}).Start();
}
}
}
finale Ware g =neue Ware();
neuer Thread(new Runnable(){
public void run(){
while(true){
g.produce("goods");
}
}
}).Start();
neuer Thread(new Runnable(){
public void run(){
while(true){
g.consume();
}
}
}).Start();
}
}
}
finale Ware g =neue Ware();
neuer Thread(new Runnable(){
public void run(){
while(true){
g.produce("goods");
}
}
},"Produzent Nr.1").start();
neuer Thread(new Runnable(){
public void run(){
while(true){
g.produce("goods");
}
}
},"Produzent Nr. 2").start();
neuer Thread(new Runnable(){
public void run(){
while(true){
g.consume();
}
}
},"Verbraucher Nr.1").start();
neuer Thread(new Runnable(){
public void run(){
while(true){
g.consume();
}
}
},"Verbraucher Nr. 2").start();
}
}
/*
Verbraucher Nr. 2 verbraucht ****** Produktnummer: 48049
Hersteller: One produziert....Artikelnummer: 48050
Verbraucher Nr. 1 verbraucht ****** Produktnummer: 48050
Hersteller: One produziert....Artikelnummer: 48051
Verbraucher Nr. 2 verbraucht ****** Produktnummer: 48051
Produzent Nr.2 produziert....Artikelnummer: 48052
Verbraucher Nr. 2 verbraucht ****** Produktnummer: 48052
Hersteller: One produziert....Artikelnummer: 48053
Verbraucher Nr. 1 verbraucht ****** Produktnummer: 48053
Hersteller: One produziert....Artikelnummer: 48054
Verbraucher Nr. 2 verbraucht ****** Produktnummer: 48054
Produzent Nr.2 produziert....Artikelnummer: 48055
Verbraucher Nr. 2 verbraucht ****** Produktnummer: 48055
*/