Java concurrent programming principle and Combat 42: Memory semantics of lock and volatile

Source: Internet
Author: User
Tags cas finally block flushes volatile

Memory semantics for Locks and volatile
    • 1. Memory Semantics of Locks
    • 2.volatile Memory semantics
    • 3.synchronized Memory semantics
    • The difference between 4.Lock and synchronized
    • 5.ReentrantLock Source code Example analysis
1. Memory Semantics of Locks

Locks are the most important synchronization mechanism in Java concurrent programming. The lock allows the thread that releases the lock to send a message to the thread that acquires the same lock, except for the exclusion of the critical zone from execution.

1.1 Lock release and acquired memory semantics

When a thread releases a lock, JMM flushes the shared variable in the local memory corresponding to that thread into main memory;
When a thread acquires a lock, JMM will have a local memory share variable that is owned by the front-line to be invalid, so that the critical section code protected by the monitor must read the shared variable from the main memory;

1.2 CAS operations

CAS is the abbreviation for the word compare and set, meaning that the value is not changed before set, and is assigned only if it is not changed.

Question: How do I implement i++ atomic operations without a lock?

CAS operations involve three operands, one is the memory value, one is the old expected value, one is the updated value, and if the memory value and the old expected value are not changed, it is set to the new value.

  public final int incrementAndGet() {    for (;;) {        //得到预期值        int current = get();        //得到更新后的值        int next = current + 1;        //通过CAS操作验证是否发生变化        if (compareAndSet(current, next))            return next;    }}

The atomic nature of CAS is actually CPU-implemented.

CAS operational uses: You can use CAs to achieve atomic operation without locking, but to clear the application, very simple operation and do not want to introduce a lock can consider the use of CAS operation, when you want to do a non-blocking operation can also consider CAs. The introduction of CAs in complex operations is not recommended, which makes the program less readable and difficult to test, and ABA problems occur.

2.volatile Memory semantics

Features of the 2.1 volatile keyword:

(1)可见性:对一个volatile关键字的读,总是能看到(任意线程)对这个关键字的写(2)原子性:对任意单个volatile变量的写操作,具有原子性(注:多个volatile组合操作不具有原子性)
    • When performing volatile writes, JMM flushes the local memory corresponding to the thread (not the actual, also called TLB, thread-local buffer) to the main memory. This process can be understood as thread 1 (the thread that executes the Write method) sends a message to the thread that next reads the variable (the thread that executes the Read method)
    • When performing a volatile read, JMM sets the local memory corresponding to the thread to be invalid. The thread next reads the value of the shared variable directly from the main memory. This process can be understood as thread 2 received a message sent by thread 1

2.2 Memory semantics

    • When a volatile variable is written, jmm flushes the corresponding shared variable value in the local variable to main memory
    • When a volatile variable is read, JMM stores the value of the thread-local variable as an invalid value, and the thread then reads the shared variable from the main memory

2.3 Implementation Principle

instance = new Singleton(); 定义一个volatile变量

Its corresponding compiled CPU instructions are:

0x01a3de1d: movb $0×0,0×1104800(%esi);0x01a3de24: lock addl $0×0,(%esp);

As can be seen from the compiled assembly instructions, the change instruction is more than one lock prefix than the other instructions

The lock prefix directive causes two things to happen under a multi-core processor:

    • Writes data from the current processor cache row back to main memory
    • This writeback process will invalidate the data that is cached in the other processor's memory address.

Specific implementation Details:

    • Lock bus: Early implementation, when the CPU reads the shared variable will lock the bus, because the CPU and other parts of the communication is implemented through the bus, if the bus is locked, the CPU can not communicate with other components, the CPU is waiting for the state, resulting in inefficient overall system.
    • Lock Cache & Cache Consistency protocol: When the CPU writes the data, if the variable that finds the action is a shared variable, that is, a copy of the variable exists in the other CPU, a signal is signaled to the other CPU that the cache row of the variable is invalid, so when the other CPU needs to read the variable, The cache line that caches the variable in its own cache is not valid, and it is re-read from memory.
Summary:

The implementation of memory semantics for locks is related to reentrant locks, and the implementation of memory semantics for locks can be briefly summarized in the following two ways:

    • Using the memory semantics of volatile variables
    • Using the volatile semantics included with CAs
3. Synchronized memory semantics
synchronized也称为监视器锁,由JVM控制实现,每个对象都有类似监视器一样的锁,当监视器锁被占用是对象将会处于锁定状态,每个对象有一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:
    1. If the monitor has an entry number of 0, the thread enters monitor and then sets the entry number to 1, which is the owner of the Monitor.
    2. If the thread already occupies the monitor, just re-enter, then enter the monitor number plus 1.
    3. If another thread has already occupied monitor, the thread goes into a blocking state until the number of Monitor's entry is 0, and then attempts to gain ownership of the monitor again.

When the thread executes the monitorexit instruction, the process is as follows:
The thread executing the monitorexit must be the owner of the monitor that corresponds to ObjectRef.

When the instruction is executed, the monitor enters the number minus 1, and if the number is 0 after minus 1, the thread exits monitor and is no longer the owner of the Monitor. Other threads that are blocked by this monitor can try to get ownership of the monitor.

Through these two paragraphs, we should be able to clearly see the implementation of the principle of synchronized, synchronized semantic bottom is through a monitor object to complete, in fact, wait/notify and other methods are also dependent on the monitor object, This is why it is only possible to call wait/notify and other methods in a synchronized block or method, or else the cause of the java.lang.IllegalMonitorStateException exception will be thrown.
  

The process of adding a lightweight lock is simple: A lock record is generated in the stack frame of the current thread, and the lock record is much simpler than the previous object lock (the monitor that manages the thread queue), which is just a copy of the object's header. Then change the tag in the object header to 00 and put the lock record address in the object header in the stack frame. If the operation is successful, the light-weight lock operation is completed. If this is not successful, the thread is competing, you will need to generate a weight lock on the current object for multi-threaded synchronization, then change the tag state to 10 and generate the monitor object (the weight lock object), and the object header will be placed in the address of the monitor object. Finally, the current thread T is queued in the queue.

The unlocking process of the light-weight lock is also simple to copy the lock record in the stack frame to the object head, if the replacement succeeds, the unlock is complete, if the substitution is unsuccessful, the other thread also competes for the lock during the time the current thread holds the lock, and the lock is upgraded to a weight lock. You need to wake up a thread in the wait queue of monitor to re-compete the lock.

4. The difference between lock and synchronized
    1. Lock has the same concurrency and memory semantics as synchronized, and the implementation of lock relies on CPU-level instruction control, and the implementation of synchronized is mainly controlled by the JVM.
    2. Synchronized in the event of an exception, the lock is automatically released by the thread, and therefore does not cause a deadlock, and lock is most likely to cause a deadlock if it fails to release the lock voluntarily through unlock () when an exception occurs. Therefore, lock must be released in the finally block when using lock;
    3. Lock allows the thread that waits for the lock to respond to interrupts, while synchronized does not, and when the synchronized is used, the waiting thread waits and fails to respond to interrupts;
    4. Lock can be used to know if there is a successful acquisition of locks, and synchronized is unable to do so. In terms of performance, if competitive resources are not intense, the performance of both is similar, and when competitive resources are very intense (that is, there are a lot of threads competing at the same time), then lock performance is far better than synchronized. Therefore, in the specific use, according to the appropriate circumstances to choose.
The difference between the two concepts:
1. 两者都是可重入的锁;2. synchronized就不是可中断锁,而Lock是可中断锁;3. synchronized是非公平锁,而lock提供公平锁的实现;4. Lock提供读写两种锁操作;

Performance comparison:

In JDK1.5, the performance of synchronized is relatively low, thread blocking and wake-up is done by the operating system kernel, frequent locking and release locks lead to frequent context switching, resulting in inefficient, so in a multithreaded environment, synchronized throughput drops very seriously. However, many optimizations were made to synchronized during the JDK1.6, including biased locking, adaptive spin, and lightweight locking.

When the following advanced features are required, you should use Lock: A timed, polled, and interruptible Lock acquisition operation, a fair queue, or a lock that is not a block structure. Otherwise, please use synchronized.

Reentrantlock Source code Example analysis

Https://www.cnblogs.com/pony1223/p/9428248.html

Java concurrent programming principle and Combat 42: Memory semantics of lock and volatile

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.