Wenn im gesamten Prozess vom Anfang eines Threads bis zum Ende des Zugriffs ein Zugriffsobjekt von einem anderen Thread geändert wird, tritt für den aktuellen Thread ein Thread-Sicherheitsproblem auf ; if Während des gesamten Zugriffsprozesses wird kein Objekt von anderen Threads verändert, was bedeutet, dass es threadsicher ist.
Das erste ist eine Multithread-Umgebung Es gibt mehrere Threads gleichzeitig. In der Single-Thread-Umgebung gibt es keine Thread-Sicherheitsprobleme. In einer Single-Thread-Umgebung wird jede Operation, einschließlich Änderungsoperationen, vom Bediener selbst ausgegeben. Der Bediener hat nicht nur einen klaren Zweck, wenn er die Operation ausführt, sondern ist sich auch der Auswirkungen der Operation bewusst.
Mehrere Operatoren (Threads) müssen dasselbe Objekt bedienen. Nur wenn mehrere Operatoren gleichzeitig ein Objekt bedienen, kann die Auswirkung des Verhaltens sofort übertragen werden andere Operationen wer.
Die Operationen mehrerer Operatoren (Threads) am selben Objekt müssen Änderungsoperationen umfassen. Beim gemeinsamen Lesen gibt es kein Thread-Sicherheitsproblem, da dies bei dem Objekt nicht der Fall ist geändert. Unverändert, kann keine Auswirkungen haben.
Zusammenfassend lässt sich sagen, dass die Hauptursache für Thread-Sicherheitsprobleme die Möglichkeit der gleichzeitigen Änderung gemeinsam genutzter Daten ist, d. h. wenn ein Thread liest, ist ein anderer Thread zulässig zu überarbeiten.
Entsprechend den Bedingungen, unter denen Thread-Sicherheitsprobleme auftreten, die Idee zur Lösung von Thread-Sicherheitsproblemen besteht darin, das Auftreten von Thread-Sicherheitsproblemen zu beseitigen. Problemumgebung:
Beseitigen Sie gemeinsam genutzte Daten: Mitgliedsvariablen und statische Variablen werden von mehreren Threads gemeinsam genutzt. Konvertieren Sie diese globalen Variablen in lokale Variablen und speichern Sie lokale Variablen auf dem Stapel. Wenn keine gemeinsame Nutzung zwischen Threads erfolgt, entsteht keine Umgebung, in der Thread-Sicherheitsprobleme auftreten. Beseitigen Sie die Mängel gemeinsam genutzter Daten: Wenn Sie ein Objekt benötigen, um Informationen von jedem Thread zu sammeln oder Informationen zwischen Threads zu übertragen, kann dieser Zweck nicht erreicht werden, wenn Sie das gemeinsam genutzte Objekt eliminieren.
Verwenden Sie den Thread-Synchronisationsmechanismus: Sperren Sie die Lese- und Schreibvorgänge gleichzeitig, sodass nur ein Thread gleichzeitig auf die gemeinsam genutzten Daten zugreifen kann. Wenn der Schreibvorgang nur gesperrt ist und nur ein Thread den Schreibvorgang gleichzeitig ausführen kann und der Lesevorgang nicht eingeschränkt ist, sodass mehrere Threads gleichzeitig lesen können, können nicht wiederholbare Lesevorgänge auftreten, z. B. ein Lesevorgang Hält lange an. Threads lesen die Daten über einen langen Zeitraum an derselben Indexposition des Arrays inkonsistent sein. Ob sowohl das Lesen als auch das Schreiben oder nur das Schreiben gesperrt werden soll, hängt von den spezifischen Anforderungen ab. Der Nachteil des Synchronisationsmechanismus besteht darin, dass er den Durchsatz des Programms verringert.
Eine Kopie erstellen: Verwenden Sie ThreadLocal, um eine Kopie der Variablen für jeden Thread zu erstellen. Jeder Thread arbeitet unabhängig, ohne sich gegenseitig zu beeinflussen. Bei dieser Methode handelt es sich im Wesentlichen um eine Implementierung zur Eliminierung der Idee gemeinsamer Daten.
4. Sichtbarkeit
Jeder Thread hält eine Kopie der gemeinsam genutzten Variablen. Wenn ein Thread die gemeinsame Variable aktualisiert, kann dies möglicherweise ein Beispiel für sexuelle Probleme sind oder nicht. 🎜>
public class NoVisibility { private static boolean ready; private static int number; public static class ReadThread extends Thread { public void run() { while(!ready ) Thread. yield(); System. out.println(number); } } public static void main(String [] args) { new ReadThread().start(); number = 42; ready = true ; } }
内置锁可以用于确保某个线程以一种可预测的方式查看另一个线程的执行结果,当线程A进入某同步代码块时,线程B随后进入由同一个锁保护的同步代码块,此时,线程B执行由锁保护的同步代码块时,可以看到线程A之前在同一同步代码块中的所有操作结果,如果没有同步,那么就无法实现上述保证。
加锁的含义不仅仅局限于互斥行为,还包括内存可见性。为了确保所有线程都能看到共享变量的最新值,所有执行读操作或者写操作的线程都必须在同一个锁上同步。
4.2、volatile变量
volatile是一种比synchronized关键字轻量级的同步机制,volatile关键字可以确保变量的更新操作通知到其他线程。
下面是volatile的典型用法:
volatile boolean asleep; ... while(!asleep) doSomeThing();
加锁机制既可以确保可见性,又可以确保原子性,而volatile变量只能确保可见性。
5、总结
编写线程安全的代码,其核心在于要对状态访问操作进行管理。编写线程安全的代码时,有两个关注点,一个是原子性问题,一个是可见性问题,要尽量避免竞态条件错误。
Das obige ist der detaillierte Inhalt vonJavas Erklärung der Prinzipien von Multithread-Sicherheitsproblemen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!