1. Das Konzept von Prozess und Thread
(1) In herkömmlichen Betriebssystemen können Programme nicht unabhängig ausgeführt werden, und da die grundlegenden Einheiten der Ressourcenzuweisung und des unabhängigen Betriebs alle Prozesse sind.
In Systemen ohne Betriebssystem ist die Ausführungsmethode der Programme eine sequentielle Ausführung, dh ein Programm muss ausgeführt werden, bevor ein anderes Programm ausgeführt werden kann. In einer Umgebung mit mehreren Programmen dürfen mehrere Programme gleichzeitig ausgeführt werden. Es gibt signifikante Unterschiede zwischen den beiden Ausführungsweisen eines Programms. Es ist genau dieses Merkmal der gleichzeitigen Ausführung von Programmen, die zur Einführung des Prozesses im Betriebssystem führt.
Seitdem die Menschen das Konzept der Prozesse in den 1960er Jahren vorgeschlagen haben, wurden in OS immer Prozesse als grundlegende Einheit verwendet, die Ressourcen haben und unabhängig laufen kann. Bis Mitte der 1980er Jahre schlugen die Personen eine Grundeinheit vor, die unabhängig voneinander ausgeführt werden kann. Threads, die kleiner als Prozesse sind, um zu versuchen, sie zu verwenden, um den Grad der gleichzeitigen Ausführung von Programmen innerhalb des Systems zu erhöhen, wodurch der Systemdurchsatz weiter erhöht wird. Insbesondere nach dem Eintritt in die 1990er Jahre haben sich Multi-Processor-Systeme schnell entwickelt. Themen können die parallele Ausführung von Programmen besser verbessern als Prozesse und die Vorteile von Multi-Processoren vollständig ausüben. Daher wurden Threads im in den letzten Jahren eingeführten Multi-Processor-Betriebssystem eingeführt, um die Leistung des Betriebssystems zu verbessern.
»Das obige wird aus " Computerbetriebssystem - herausgegeben - bearbeitet von Tang Xiaodan und anderen - Ausgabe 3 " (Download -Adresse)
(2) Die folgende Abbildung ist eine Erklärung von Zhihu -Benutzern:
Durch das obige allgemeine Verständnis wissen wir im Grunde, welche Themen und Prozesse es tun. Fassen wir also das Konzept für Prozesse und Threads unten zusammen:
(3) Prozess ist eine laufende Aktivität eines Programms in einem Computer über einen bestimmten Datensatz, die grundlegende Einheit der Ressourcenzuweisung und -planung des Systems und die Grundlage für die Betriebssystemstruktur. In den frühen prozessorientierten Computerstrukturen waren Prozesse die grundlegenden Ausführungseinheiten von Programmen; In den zeitgenössischen threadorientierten Computerstrukturen waren Prozesse Container von Threads. Ein Programm ist eine Beschreibung von Anweisungen, Daten und seiner organisatorischen Form, und ein Prozess ist eine Einheit eines Programms.
(4) Fäden, die manchmal als Leicht- (LWP) bezeichnet werden, sind die kleinste Einheit des Programmausführungsflusss. Threads sind ein einzelner sequentieller Steuerungsprozess in einem Programm. Eine relativ unabhängige und planmäßige Ausführungseinheit im Prozess ist die grundlegende Einheit der unabhängigen Planung und Versand von CPU im System, das sich auf die Planungseinheit für Auslaufprogramme bezieht. Ausführen mehrerer Threads gleichzeitig in einem einzigen Programm, um verschiedene Arbeiten zu erledigen, die als Multithreading bezeichnet werden.
(5) Die Beziehung zwischen Prozess und Thread:
2. Java implementiert Multi-Threading-Methode
(1) Erben von Thread und schreiben Sie die Run () -Methode neu auf
öffentliche Klasse MyThread erweitert Thread {@Override public void run () {while (true) {System.out.println (this.currentThread (). getName ()); }} public static void main (String [] args) {myThread thread = new myThread (); Thread.Start (); // die richtige Art, Thread zu starten}}Ausgangsergebnis:
Thread-0Thread-0Thread-0 ...
Zusätzlich müssen Sie verstehen, dass die Start () -Methode die Start () -Methode anstelle der Run () -Methode ist. Wenn die Run () -Methode verwendet wird, ist es eine gewöhnliche Methode zum Ausführen.
(2) Implementieren Sie die ablaufbare Schnittstelle
public class myrunnable implements runnable {@Override public void run () {System.out.println ("123"); } public static void main (String [] args) {Myrunnable Myrunnable = new Myrunnable (); Thread = neuer Thread (myrunnable, "t1"); Thread.Start (); }}3. Fadensicherheit
Thread-Sicherheitskonzept: Wenn mehrere Threads auf eine bestimmte Klasse (Objekt oder Methode) zugreifen, kann die Klasse immer das richtige Verhalten anzeigen, und dann ist diese Klasse (Objekt oder Methode) Thread-Safe.
Die Sicherheit der Gewinde ist beim Zugriff auf Multi-Threads, ein Verriegelungsmechanismus wird übernommen. Wenn ein Thread auf bestimmte Daten der Klasse zugreift, ist er geschützt. Andere Threads können nicht darauf zugreifen, wenn der Thread ihn gelesen hat und andere Threads es nicht verwenden können. Es gibt keine Datenkonsistenz oder Datenverschmutzung. Themen sind nicht sicher, was bedeutet, dass sie keinen Datenzugriffsschutz bieten. Es ist möglich, dass mehrere Threads die Daten nacheinander ändern, was dazu führt, dass die resultierenden Daten schmutzig sind. Der gemeinsame Verriegelungsmechanismus hier ist: synchronisiert
4. Synchronisierter Modifikator
(1) Synchronisiert: Sie können jedem Objekt und einer beliebigen Methode Sperren hinzufügen, und der gesperrte Code wird als "Mutex -Bereich" oder "kritischer Bereich" bezeichnet.
(2) ** Verwenden Sie nicht ** Synchronisierte Instanz (Code A):
öffentliche Klasse MyThread erweitert Thread {private int count = 5; @Override public void run () {count-; Thread (MyThread, "Thread2"); Thread Thread3 = neuer Thread (MyThread, "Thread3"); Thread 4 = neuer Thread (MyThread, "Thread4"); Thread5 = neuer Thread (MyThread, "Thread5"); Thread1.start (); Thread2.Start (); Thread3.start (); Thread4.Start ();Ein Ergebnis der Ausgabe ist wie folgt:
Thread3 Graf: 2Thread4 Count: 1Thread1 Count: 2Thread2 Count: 3Thread5 Count: 0
Es ist ersichtlich, dass das obige Ergebnis falsch ist, da mehrere Threads die Run () -Methode gleichzeitig bedienen und die Anzahl ändern, was wiederum einen Fehler verursacht.
(3) ** Verwenden Sie ** Synchronisierte Instanz (Code B):
öffentliche Klasse MyThread erweitert Thread {private int count = 5; @Override public synchronisierte void run () {count--; System.out.println (this.currentThread (). GetName () + "count:" + count); } public static void main (String [] args) {MyThread myThread = new myThread (); Thread Thread1 = neuer Thread (MyThread, "Thread1"); Thread2 = neuer Thread (MyThread, "Thread2"); Thread Thread3 = neuer Thread (MyThread, "Thread3"); Thread 4 = neuer Thread (MyThread, "Thread4"); Thread Thread5 = neuer Thread (MyThread, "Thread5"); Thread1.Start (); thread2.Start (); thread3.Start (); thread4.Start (); Thread5.Start (); }}Ausgangsergebnis:
Thread1 Graf: 4Thread2 Count: 3Thread3 Count: 2Thread5 Count: 1Thread4 Count: 0
Es ist ersichtlich, dass der Unterschied zwischen Code A und Code B darin besteht, dass die methode run () synchronisierte Modifikationen hinzugefügt wird.
Die Beschreibung lautet wie folgt:
Wenn mehrere Threads auf die MyThread-Laufmethode zugreifen, wird das Multi-Thread in einer Warteschlange verarbeitet (die Warteschlange wird hier gemäß der Reihenfolge der CPU-Zuordnung bestimmt). Wenn ein Thread den Code in der synchronisierten Modifikationsmethode ausführen möchte, versucht er zunächst, die Sperre zu erhalten. Wenn es das Schloss erhält, führt der Inhalt der synchronisierten Codekörper aus. Wenn es das Schloss nicht erhalten kann, versucht der Thread weiterhin, das Schloss zu erhalten, bis es es bekommt. Darüber hinaus konkurrieren mehrere Threads gleichzeitig um das Schloss, was bedeutet, dass der Sperrwettbewerb auftritt.
5. Ein Objekt hat ein Schloss! Mehrere Threads und mehrere Schlösser!
Was ist, ein Objekt hat eine Sperre, mehrere Threads haben mehrere Sperren! Schauen wir uns zunächst den Beispielcode unten an (Code C):
öffentliche Klasse MultitHhread {private int num = 200; public synchronisierte void printNum (String -ThreadName, String -Tag) {if (tag.equals ("a")) {num = num - 100; System.out.println (ThreadName + "Tag A, Num Setzen Sie num!"); } else {num = num - 200; System.out.println (ThreadName + "Tag" + Tag + ", num =" + num); } public static void main (String [] args) löst InterruptedException aus {endgültig multithread multithread1 = new multithread (); endgültig multithread multithread2 = new multithread (); neuer Thread (new Runnable () {public void run () {multitHhread1.printnum ("Thread1", "a");}}). start (); Thread.sleep (5000); System.out.println ("Warte 5 Sekunden, um sicherzustellen, dass Thread1 ausgeführt wurde!"); neuer Thread (new Runnable () {public void run () {multithread2.printnum ("thread2", "b");}}). start (); }}Ausgangsergebnis:
Thread1 Tag A, Num über! Thread1 Tag A, Num = 100wait 5 Sekunden, um sicherzustellen, dass Thread1 ausgeführt wurde! Thread2 Tag B, Num über! Thread2 Tag B, num = 0 setzen
Es ist zu erkennen, dass es zwei Objekte gibt: Multithread1 und Multithread2. Wenn mehrere Objekte dieselbe Sperre verwenden, sollte das Ergebnis der obigen Ausführung: Thread2 -Tag B, num = -100 sein. Daher hat jedes Objekt das Schloss dieses Objekts.
Die vom Keyword Synchronisierten Keyword erhaltenen Schlösser sind Objektsperrungen, anstatt ein Code oder eine Methode als Sperren zu behandeln. Daher hält der Thread im obigen Beispielcode C, in dem zuerst die synchronisierte Schlüsselwortmethode ausgeführt wird, die Sperre des Objekts, zu dem die Methode gehört. Der Faden erhält zwei verschiedene Schlösser von zwei verschiedenen Objekten und ergänzt sich gegenseitig.
In normalen Szenarien muss es also eine Situation geben, in der alle Objekte mit einer variablen Anzahl arbeiten. Wie implementieren Sie sie also? Es ist sehr einfach, statisch hinzuzufügen. Wir wissen, dass alle Objekte in dieser Klasse die gleiche Referenz haben, unabhängig davon, wie viele Objekte instanziiert sind, der Anruf ist eine Methode und der Code ist wie folgt (Code D):
public class multithread {private static int num = 200; public static synchronisierte void printNum (String -ThreadName, String -Tag) {if (tag.equals ("a")) {num = num - 100; System.out.println (ThreadName + "Tag A, Num Setzen Sie num!"); } else {num = num - 200; System.out.println (ThreadName + "Tag B, Num Setzen Sie num!"); } System.out.println (ThreadName + "Tag" + Tag + ", num =" + num); } public static void main (String [] args) löst InterruptedException aus {endgültig multithread multithread1 = new multithread (); endgültig multithread multithread2 = new multithread (); neuer Thread (new Runnable () {public void run () {multitHhread1.printnum ("Thread1", "a");}}). start (); Thread.sleep (5000); System.out.println ("Warte 5 Sekunden, um sicherzustellen, dass Thread1 ausgeführt wurde!"); neuer Thread (new Runnable () {public void run () {multithread2.printnum ("thread2", "b");}}). start (); }}Ausgangsergebnis:
Thread1 Tag A, Num über! Thread1 Tag A, Num = 100wait 5 Sekunden, um sicherzustellen, dass Thread1 ausgeführt wurde! Thread2 Tag B, Num über! Thread2 Tag B, Num = -100 einstellen
Es ist ersichtlich, dass das Hinzufügen einer statischen Modifikation zu Variablen und Methoden die Szenarien realisieren kann, die wir benötigen. Es zeigt auch, dass für nicht statische statische Modifikationsmethoden oder Variablen ein gesperrtes Objekt.
6. Synchrone und asynchrone Objektschlösser
(1) synchronisiert
Das Konzept der Synchronisation ist das Teilen. Wir müssen wissen, dass das Wort "Teilen" keine gemeinsame Ressource ist, es besteht keine Notwendigkeit, zu synchronisieren, dh keine Notwendigkeit, es zu sperren.
Der Zweck der Synchronisation besteht darin, die Sicherheit von Fäden zu gewährleisten. In der Tat müssen zwei grundlegendste Merkmale erfüllt sein: Atomizität und Sichtbarkeit;
(2) Asynchronisiert: Asynchronisiert
Das Konzept der Asynchronität ist die Unabhängigkeit, ohne dass sich zwischeneinander einschränken, und es gibt keine Beziehung zwischen den beiden.
(3) Beispielcode:
public class myObject {public void method () {System.out.println (Thread.CurrentThread (). getName ()); } public static void main (String [] args) {endgültig myObject myObject = new myObject (); Thread t1 = neuer Thread (neuer runnable () {public void run () {myObject.method ();}}, "t1"); Thread t2 = neuer Thread (new Runnable () {public void run () {myObject.method ();}}, "t2"); t1.start (); t2.Start (); }}Im obigen Code ist Methode () eine asynchrone Methode.
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels über die anfängliche Lösung für das Konzept des Threading, Verfahrens und Synchrones in Java-Multi-Threading. Ich hoffe, es wird für alle hilfreich sein. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht und weisen Sie sie darauf hin, und der Herausgeber wird allen rechtzeitig antworten.