Was ist der Unterschied zwischen synchronisiert und gesperrt?
Nov 19, 2020 am 11:38 AM區(qū)別:1、lock是一個(gè)接口,而synchronized是java的一個(gè)關(guān)鍵字。2、synchronized在發(fā)生異常時(shí)會(huì)自動(dòng)釋放占有的鎖,因此不會(huì)出現(xiàn)死鎖;而lock發(fā)生異常時(shí),不會(huì)主動(dòng)釋放占有的鎖,必須手動(dòng)來(lái)釋放鎖,可能引起死鎖的發(fā)生。
在分布式開(kāi)發(fā)中,鎖是線程控制的重要途徑。Java為此也提供了2種鎖機(jī)制,synchronized和lock。
0、synchronized實(shí)現(xiàn)原理
Java中每一個(gè)對(duì)象都可以作為鎖,這是synchronized實(shí)現(xiàn)同步的基礎(chǔ):
普通同步方法,鎖是當(dāng)前實(shí)例對(duì)象
靜態(tài)同步方法,鎖是當(dāng)前類(lèi)的class對(duì)象
同步方法塊,鎖是括號(hào)里面的對(duì)象
當(dāng)一個(gè)線程訪問(wèn)同步代碼塊時(shí),它首先是需要得到鎖,當(dāng)退出或者拋出異常時(shí)必須要釋放鎖,那么它是如何來(lái)實(shí)現(xiàn)這個(gè)機(jī)制的呢?我們先看一段簡(jiǎn)單的代碼:
package cn.alibab.javap;public class SynchronizedTest { public synchronized void test1(){ } public void test2(){ synchronized (this){ } } }
利用javap工具(javap是java編譯之后的class文件的分解器)查看生成的class文件信息來(lái)分析Synchronized的實(shí)現(xiàn)
從上面可以看出,同步代碼塊是使用monitorenter和monitorexit指令實(shí)現(xiàn)的,同步方法(在這看不出來(lái)需要看JVM底層實(shí)現(xiàn))依靠的是方法修飾符上的ACC_SYNCHRONIZED實(shí)現(xiàn)。
同步代碼塊:monitorenter指令是在編譯后插入到同步代碼塊的開(kāi)始位置,monitorexit指令插入到同步代碼塊的結(jié)束位置,JVM需要保證每一個(gè)monitorenter都有一個(gè)monitorexit與之相對(duì)應(yīng)。任何對(duì)象都有一個(gè)monitor與之相關(guān)聯(lián),當(dāng)且一個(gè)monitor被持有之后,他將處于鎖定狀態(tài)。線程執(zhí)行到monitorenter指令時(shí),將會(huì)嘗試獲取對(duì)象所對(duì)應(yīng)的monitor所有權(quán),即嘗試獲取對(duì)象的鎖;【摘自并發(fā)編程藝術(shù)】
同步方法:synchronized方法則會(huì)被翻譯成普通的方法調(diào)用和返回指令如:invokevirtual、areturn指令,在VM字節(jié)碼層面并沒(méi)有任何特別的指令來(lái)實(shí)現(xiàn)被synchronized修飾的方法,而是在Class文件的方法表中將該方法的access_flags字段中的synchronized標(biāo)志位置1,表示該方法是同步方法并使用調(diào)用該方法的對(duì)象或該方法所屬的Class在JVM的內(nèi)部對(duì)象表示Klass做為鎖對(duì)象。(摘自:http://www.cnblogs.com/javaminer/p/3889023.html)
synchronized和lock的區(qū)別
區(qū)別如下:
來(lái)源:
lock是一個(gè)接口,而synchronized是java的一個(gè)關(guān)鍵字,synchronized是內(nèi)置的語(yǔ)言實(shí)現(xiàn);異常是否釋放鎖:
synchronized在發(fā)生異常時(shí)候會(huì)自動(dòng)釋放占有的鎖,因此不會(huì)出現(xiàn)死鎖;而lock發(fā)生異常時(shí)候,不會(huì)主動(dòng)釋放占有的鎖,必須手動(dòng)unlock來(lái)釋放鎖,可能引起死鎖的發(fā)生。(所以最好將同步代碼塊用try catch包起來(lái),finally中寫(xiě)入unlock,避免死鎖的發(fā)生。)是否響應(yīng)中斷
lock等待鎖過(guò)程中可以用interrupt來(lái)中斷等待,而synchronized只能等待鎖的釋放,不能響應(yīng)中斷;是否知道獲取鎖
Lock可以通過(guò)trylock來(lái)知道有沒(méi)有獲取鎖,而synchronized不能;Lock可以提高多個(gè)線程進(jìn)行讀操作的效率。(可以通過(guò)readwritelock實(shí)現(xiàn)讀寫(xiě)分離)
在性能上來(lái)說(shuō),如果競(jìng)爭(zhēng)資源不激烈,兩者的性能是差不多的,而當(dāng)競(jìng)爭(zhēng)資源非常激烈時(shí)(即有大量線程同時(shí)競(jìng)爭(zhēng)),此時(shí)Lock的性能要遠(yuǎn)遠(yuǎn)優(yōu)于synchronized。所以說(shuō),在具體使用時(shí)要根據(jù)適當(dāng)情況選擇。
synchronized使用Object對(duì)象本身的wait 、notify、notifyAll調(diào)度機(jī)制,而Lock可以使用Condition進(jìn)行線程之間的調(diào)度,
//Condition定義了等待/通知兩種類(lèi)型的方法 Lock lock=new ReentrantLock(); Condition condition=lock.newCondition();...condition.await();...condition.signal(); condition.signalAll();
1、synchronized和lock的用法區(qū)別
synchronized:在需要同步的對(duì)象中加入此控制,synchronized可以加在方法上,也可以加在特定代碼塊中,括號(hào)中表示需要鎖的對(duì)象。
lock:一般使用ReentrantLock類(lèi)做為鎖。在加鎖和解鎖處需要通過(guò)lock()和unlock()顯示指出。所以一般會(huì)在finally塊中寫(xiě)unlock()以防死鎖。
2、synchronized和lock性能區(qū)別
synchronized是托管給JVM執(zhí)行的,
而lock是java寫(xiě)的控制鎖的代碼。
In Java 1.5 ist die Synchronisierung leistungsineffizient. Da es sich hierbei um eine schwere Operation handelt, die den Aufruf der Operationsschnittstelle erfordert, kann das Sperren mehr Systemzeit beanspruchen als andere Vorg?nge als das Sperren. Im Gegensatz dazu bietet die Verwendung des von Java bereitgestellten Lock-Objekts eine h?here Leistung.
Aber mit Java 1.6 haben sich die Dinge ge?ndert. Synchronize ist semantisch sehr klar und kann viele Optimierungen durchführen, einschlie?lich adaptivem Spin, Sperrenbeseitigung, Sperrvergr?berung, leichtgewichtiger Sperre, voreingenommener Sperre usw. Infolgedessen ist die Leistung von Synchronize unter Java1.6 nicht schlechter als die von Lock. Beamte gaben au?erdem an, dass sie auch die Synchronisierung st?rker unterstützen und es in zukünftigen Versionen Raum für Optimierungen gebe.
Die spezifischen Unterschiede zwischen den beiden Mechanismen:
Synchronized verwendete ursprünglich den pessimistischen CPU-Sperrmechanismus, dh der Thread erh?lt eine exklusive Sperre. Exklusive Sperre bedeutet, dass andere Threads nur auf die Blockierung warten k?nnen, bis der Thread die Sperre aufhebt. Wenn der CPU-Konvertierungsthread blockiert ist, führt dies zu einem Thread-Kontextwechsel. Wenn viele Threads um die Sperre konkurrieren, führt dies zu einem h?ufigen Kontextwechsel der CPU, was zu einer sehr geringen Effizienz führt.
Und Lock verwendet eine optimistische Sperrmethode. Die sogenannte optimistische Sperre besteht darin, einen Vorgang jedes Mal ohne Sperre abzuschlie?en, jedoch unter der Annahme, dass kein Konflikt vorliegt. Wenn er aufgrund eines Konflikts fehlschl?gt, wird er wiederholt, bis er erfolgreich ist. Der durch optimistische Sperren implementierte Mechanismus ist die CAS-Operation (Compare and Swap). Wenn wir den Quellcode von ReentrantLock weiter untersuchen, werden wir feststellen, dass eine der wichtigeren Methoden zum Erhalten der Sperre CompareAndSetState ist. Dies ist eigentlich die spezielle Anweisung, die von der aufgerufenen CPU bereitgestellt wird.
Moderne CPUs stellen Anweisungen bereit, die gemeinsam genutzte Daten automatisch aktualisieren und St?rungen durch andere Threads erkennen k?nnen. CompareAndSet() verwendet diese anstelle von Sperren. Dieser Algorithmus wird als nicht blockierender Algorithmus bezeichnet. Dies bedeutet, dass der Ausfall oder die Unterbrechung eines Threads keinen Einfluss auf den Ausfall oder die Unterbrechung anderer Threads haben sollte.
3. Der Unterschied zwischen synchronisierten und Sperrzwecken
Unter normalen Umst?nden gibt es keinen Unterschied zwischen synchronisierten Grundelementen und ReentrantLock. Bei sehr komplexen Synchronisierungsanwendungen sollten Sie jedoch die Verwendung von ReentrantLock in Betracht ziehen, insbesondere wenn Sie auf die folgenden beiden Anforderungen sto?en.
1. Ein bestimmter Thread muss unterbrochen werden, w?hrend er auf die Kontrolle einer Sperre wartet. 2. Einige Wartebenachrichtigungen müssen separat verarbeitet werden. Die Bedingungsanwendung in ReentrantLock kann steuern, welcher Thread benachrichtigt werden soll. 3. Es gibt eine faire Sperre Funktion. Jeder eingehende Thread wird in der Schlange stehen
Lass uns im Detail darüber reden...
Lass uns zuerst über den ersten Fall sprechen. Es gibt zwei Sperrmechanismen von ReentrantLock, die Interrupt-Sperren ignorieren und auf Interrupt-Sperren reagieren viele Probleme. Gro?e Flexibilit?t. Beispiel: Wenn zwei Threads A und B um eine Sperre konkurrieren, erh?lt Thread A die Sperre und Thread B wartet. Allerdings hat Thread A zu diesem Zeitpunkt wirklich zu viele Dinge zu erledigen und kann Thread B m?glicherweise nicht zurückgeben Ich m?chte noch l?nger warten, aufh?ren, auf diese Sperre zu warten, und mich anderen Dingen zuwenden. Zu diesem Zeitpunkt bietet
ReentrantLock zwei Mechanismen: unterbrechbar/nicht unterbrechbar Erstens unterbricht Thread B sich selbst (oder andere Threads unterbrechen ihn), aber ReentrantLock antwortet nicht und l?sst Thread B weiterhin warten, I taub geworden (dies ist beim synchronisierten Grundelement der Fall); Zweitens unterbricht sich der B-Thread selbst (oder andere Threads unterbrechen ihn), ReentrantLock verarbeitet den Interrupt und wartet nicht mehr auf das Eintreffen der Sperre, sondern gibt vollst?ndig auf .
Weitere Kenntnisse zum Thema Programmierung finden Sie unter:
Das obige ist der detaillierte Inhalt vonWas ist der Unterschied zwischen synchronisiert und gesperrt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Hei?e KI -Werkzeuge

Undress AI Tool
Ausziehbilder kostenlos

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem v?llig kostenlosen KI-Gesichtstausch-Tool aus!

Hei?er Artikel

Hei?e Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Um JDBC -Transaktionen korrekt zu verarbeiten, müssen Sie zun?chst den automatischen Komiti -Modus ausschalten und dann mehrere Vorg?nge ausführen und schlie?lich entsprechend den Ergebnissen festlegen oder rollen. 1. Nennen Sie Conn.SetAutoCommit (False), um die Transaktion zu starten. 2. Führen Sie mehrere SQL -Operationen aus, z. B. einfügen und aktualisieren. 3. Rufen Sie Conn.Commit () an, wenn alle Vorg?nge erfolgreich sind, und rufen Sie Conn.Rollback () auf, wenn eine Ausnahme auftritt, um die Datenkonsistenz zu gew?hrleisten. Gleichzeitig sollten Try-with-Ressourcen verwendet werden, um Ressourcen zu verwalten, Ausnahmen ordnungsgem?? zu behandeln und Verbindungen zu schlie?en, um Verbindungsleckage zu vermeiden. Darüber hinaus wird empfohlen, Verbindungspools zu verwenden und Save -Punkte zu setzen, um teilweise Rollback zu erreichen und Transaktionen so kurz wie m?glich zu halten, um die Leistung zu verbessern.

Verwenden Sie Klassen im Java.Time -Paket, um das alte Datum und die Kalenderklassen zu ersetzen. 2. Erhalten Sie das aktuelle Datum und die aktuelle Uhrzeit durch LocalDate, LocalDatetime und Local Time; 3. Erstellen Sie ein bestimmtes Datum und eine bestimmte Uhrzeit mit der von () Methode; 4.. Verwenden Sie die Plus/Minus -Methode, um die Zeit nicht zu erh?hen und zu verkürzen. 5. Verwenden Sie ZonedDatetime und zoneId, um die Zeitzone zu verarbeiten. 6. Format und analysieren Sie Datumszeichenfolgen über DateTimeFormatter; 7. Verwenden Sie sofortige, um bei Bedarf mit den alten Datumstypen kompatibel zu sein. Die Verarbeitung der Datum in der modernen Java sollte der Verwendung von Java.Timeapi vorrangig machen, was klare, unver?nderliche und linear ist

Pre-Formancetartuptimemoryusage, QuarkusandmicronautleadduToCompile-Time-foringandgraalvSupport, WithQuarkusofttenperformLightBetterin serverloser Szenarien.2. Thyvelopecosystem,

HTTP-Protokoll Middleware in Go kann Anforderungsmethoden, Pfade, Client-IP und zeitaufw?ndiges Aufzeichnen aufzeichnen. 1. Verwenden Sie http.Handlerfunc, um den Prozessor zu wickeln, 2. Nehmen Sie die Startzeit und die Endzeit vor und nach dem Aufrufen als n?chstes auf. Der vollst?ndige Beispielcode wurde überprüft, um auszuführen und eignet sich zum Starten eines kleinen und mittelgro?en Projekts. Zu den Erweiterungsvorschl?gen geh?ren das Erfassen von Statuscodes, die Unterstützung von JSON -Protokollen und die Nachverfolgung von ID -IDs.

Die Müllsammlung von Java (GC) ist ein Mechanismus, der automatisch den Speicher verwaltet, der das Risiko eines Speicherlecks verringert, indem unerreichbare Objekte zurückgeführt werden. 1.GC beurteilt die Zug?nglichkeit des Objekts aus dem Stammobjekt (z. B. Stapelvariablen, aktive Threads, statische Felder usw.) und nicht erreichbare Objekte als Müll markiert. 2. Basierend auf dem markierten Algorithmus markieren Sie alle erreichbaren Objekte und l?schen Sie nicht markierte Objekte. 3.. Verfolgen Sie eine Generationskollektionsstrategie: Die neue Generation (Eden, S0, S1) führt h?ufig MollGC aus; Die ?lteren Menschen erzielen weniger, dauert jedoch l?nger, um MajorGC durchzuführen. MetaPace speichert Klassenmetadaten. 4. JVM bietet eine Vielzahl von GC -Ger?ten: SerialGC ist für kleine Anwendungen geeignet; ParallelgC verbessert den Durchsatz; CMS reduziert sich

Durch die Auswahl des richtigen HTMlinput -Typs kann die Datengenauigkeit verbessert, die Benutzererfahrung verbessert und die Benutzerfreundlichkeit verbessert werden. 1. W?hlen Sie die entsprechenden Eingabetypen gem?? dem Datentyp aus, z. B. Text, E -Mail, Tel, Nummer und Datum, die automatisch überprüft und an die Tastatur anpassen k?nnen. 2. Verwenden Sie HTML5, um neue Typen wie URL, Farbe, Reichweite und Suche hinzuzufügen, die eine intuitivere Interaktionsmethode bieten k?nnen. 3.. Verwenden Sie Platzhalter und erforderliche Attribute, um die Effizienz und Genauigkeit der Formulierung zu verbessern. Es sollte jedoch beachtet werden, dass der Platzhalter das Etikett nicht ersetzen kann.

GradleStheBetterChoiceFormostnewProjectsDuetoitSuperiorFlexibilit?t, Leistung und ModerntoolingSupport.1.GRADLE'SGROOVY/KOTLINDSLISMORECONCISEANDEIPRESSIVETHANMANMANBOSEXML.2.GRAGRECONCISEANDEPRPRESSIVETHANMAVENSVOSEXML.2.

Auf Defer wird verwendet, um bestimmte Vorg?nge auszuführen, bevor die Funktion zurückgibt, z. B. die Reinigungsressourcen. Die Parameter werden sofort bewertet, wenn sie aufgeschoben werden, und die Funktionen werden in der Reihenfolge von Last-In-First-Out (LIFO) ausgeführt. 1. Mehrere Defers werden in umgekehrter Reihenfolge der Erkl?rungen ausgeführt. 2. h?ufig für die sichere Reinigung wie das Schlie?en von Dateien verwendet; 3. Der benannte Rückgabewert kann ge?ndert werden; V. 5. Vermeiden Sie den Missbrauch von Verschiebungen in Schleifen, um Ressourcenleckage zu verhindern. Die korrekte Verwendung kann die Sicherheit und die Lesbarkeit der Code verbessern.
