1. Synchronized optimization scheme
1.1 lock elimination
Lock elimination is the removal of unnecessary lock operations. The virtual machine real-time editor, at runtime, removes locks that require synchronization in code but detect that shared data contention is not possible.
According to code escape, a piece of code is considered thread-safe and does not need to be locked if it is determined that no data on the heap will escape from the current thread.
Take a look at this program:
public class SynchronizedTest {
public static void main(String[] args) {
SynchronizedTest test = new SynchronizedTest();
for (int i = 0; i < 100000000; i++) {
test.append("abc"."def"); }}public void append(String str1, String str2) {
StringBuffer sb = newStringBuffer(); sb.append(str1).append(str2); }}Copy the code
Although the append of a StringBuffer is a synchronous method, the StringBuffer in this program is a local variable and does not escape from the method. So this process is actually thread-safe and removes the lock.
1.2 lock coarsening
If a series of consecutive operations repeatedly lock and unlock the same object, even if the locking operation occurs in the body of the loop, frequent mutex synchronization can cause unnecessary performance losses even if there is no thread contention.
If the virtual machine detects a string of fragmented operations that lock the same object, the scope of lock synchronization will be extended (coarsed) outside the entire operation sequence.
Here’s an example:
public class StringBufferTest {
StringBuffer stringBuffer = new StringBuffer();
public void append(a){
stringBuffer.append("a");
stringBuffer.append("b");
stringBuffer.append("c"); }}Copy the code
Each call to stringBuffer.append requires locking and unlocking. If the virtual machine detects a series of locking and unlocking operations on the same object in a row, it will combine them into a larger locking and unlocking operation at the first append. Unlock after the last append method.
2. Precautions for synchronized use
-
Sync locks classes when applied to static methods, such as sync (a.class)
-
Sync lock granularity should be as small as possible to ensure atomicity
-
Synchronized automatically releases the lock when encountering an exception, which needs to be processed in the catch block
-
Sync can only lock heap, not String (method area – constant pool)
-
Sync is a reentrant lock that is automatically acquired by calling the sync method in the sync block
-
Simulation of a deadlock