Dieser Artikel vermittelt Ihnen relevantes Wissen über Java, in dem hauptsächlich Fragen im Zusammenhang mit den drei Elementen der gleichzeitigen Programmierung vorgestellt werden, einschließlich Atomizität, Sichtbarkeit, Ordnung, deren Ursachen und Definitionen usw. Schauen wir uns hoffentlich den folgenden Inhalt an es wird für alle hilfreich sein.
Empfohlene Studie: „Java-Video-Tutorial“
Atomizität bezieht sich auf eine oder mehrere Operationen, die entweder alle ausgeführt oder nicht unterbrochen werden durch andere Vorgänge während der Ausführung oder werden überhaupt nicht ausgeführt.
Thread-Switching ist die Ursache für Atomizitätsprobleme. Thread-Switching dient der Verbesserung der CPU-Auslastung.
Am Beispiel von count++ sind mindestens drei CPU-Anweisungen erforderlich:
Wir nehmen an, dass count=0 ist. Wenn Thread A den Thread wechselt, nachdem Anweisung 1 ausgeführt wurde, und Thread A und Thread B gemäß der Reihenfolge in der Abbildung unten ausgeführt werden, werden wir feststellen, dass beide Threads die Operation count+= ausgeführt haben 1, aber das erhaltene Ergebnis ist nicht 2, wie wir erwartet hatten, sondern 1.
In einer Multithread-Umgebung garantiert Java nur, dass Variablen und Zuweisungsoperationen grundlegender Datentypen atomar sind (Hinweis: In einer 32-Bit-JDK-Umgebung für 64-Bit-Daten Das Lesen ist keine atomare Operation*, wie z. B. long, double)
Wenn wir sicherstellen können, dass sich Änderungen an gemeinsam genutzten Variablen gegenseitig ausschließen, unabhängig davon, ob es sich um eine Single-Core-CPU oder eine handelt Multi-Core-CPU. Dadurch wird die Atomizität gewährleistet. Durch Sperren können Atomizitätsprobleme gelöst werden, z. B. durch die Verwendung von „Synchronized“ und „Lock“.
Sichtbarkeit bedeutet, dass, wenn mehrere Threads eine gemeinsam genutzte Variable bearbeiten, andere Threads sofort das Ergebnis der Änderung sehen können, nachdem einer der Threads die Variable geändert hat.
Die Datenkonsistenz zwischen CPU-Cache und Speicher ist die Ursache für Sichtbarkeitsprobleme. Der CPU-Cache soll die Effizienz der CPU verbessern.
Die Ursache des Sichtbarkeitsproblems ist der CPU-Cache. Dann können wir den CPU-Cache deaktivieren.
Die Sichtbarkeitsregel ist die Happens-Before-Regel.
Passiert-Vorher-Regel:
In einem Thread findet entsprechend der Programmsequenz die vorherige Operation statt – vor jeder nachfolgenden Operation.
class Example { public void test() { int x = 42; ① int y = 20; ② } }
① Passiert – bevor ②.
Ein Schreibvorgang für eine flüchtige Variable wird ausgeführt, bevor nachfolgende Lesevorgänge für diese flüchtige Variable ausgeführt werden.
Wenn A vor B geschieht und B vor C geschieht, dann geschieht A vor C.
class Example { int x = 0; volatile int y = 0; public void writer() { x = 42; ① y = 1; ② } public void reader() { if (y == 1) { ③ // 这里x会是多少呢? } } }
管程是一种通用的同步原语,在 Java 中指的就是 synchronized,synchronized 是 Java 里对管程的实现。
synchronized (this) { //此处自动加锁 // x是共享变量,初始值=10 if (this.x < 12) { this.x = 12; } } //此处自动解锁
假设 x 的初始值是 10,线程 A 执行完代码块后 x 的值会变成 12(执行完自动释放锁);
线程 B 进入代码块时,能够看到线程 A 对 x 的写操作,也就是线程 B 能够看到 x==12。
它是指主线程 A 启动子线程 B 后,子线程 B 能够看到主线程在启动子线程 B 前的操作。
它是指主线程 A 等待子线程 B 完成(主线程 A 通过调用子线程 B 的 join() 方法实现),当子线程 B 完成后(主线程 A 中 join() 方法返回),主线程能够看到子线程的操作。当然所谓的“看到”,指的是对共享变量的操作。
有序性,即程序的执行顺序按照代码的先后顺序来执行。
编译器为了优化性能,有时候会改变程序中语句的先后顺序。
例如:“a=6;b=7;”编译器优化后可能变成“b=7;a=6;”,在这个例子中,编译器调整了语句的顺序,但是不影响程序的最终结果。
以双重检查代码为例:
public class Singleton { static Singleton instance; static Singleton getInstance(){ if (instance == null) { ① synchronized(Singleton.class) { if (instance == null) instance = new Singleton(); ② } } return instance; } }
上面的代码有问题,问题在 ② 操作上:经过优化后的执行路径是这样的:
优化后会导致什么问题呢?我们假设线程 A 先执行 getInstance() 方法,当执行完 ① 时恰好发生了线程切换,切换到了线程 B 上;如果此时线程 B 也执行 getInstance() 方法,那么线程 B 在执行第一个判断时会发现 instance != null ,所以直接返回 instance,而此时的 instance 是没有初始化过的,如果我们这个时候访问 instance 的成员变量就可能触发空指针异常。
如何解决双重检查问题?变量用 volatile 来修饰,禁止指令重排序。
public class Singleton { static volatile Singleton instance; static Singleton getInstance(){ if (instance == null) { ① synchronized(Singleton.class) { if (instance == null) instance = new Singleton(); ② } } return instance; } }
推荐学习:《java视频教程》
Das obige ist der detaillierte Inhalt vonErfahren Sie mehr über die drei Elemente der gleichzeitigen Java-Programmierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!