preface

In the previous article, the article thoroughly understand the interview often ask “” lock” introduced the “lock” in Java, in May is not very understanding of these concepts for students will feel a little around, so I decided to split up, step by step detailed introduce the cause and effect of these locks, so this article will first “spin lock” for a while.

The body of the

A reason for

In our program, if there is a large number of mutually exclusive synchronization code, when high concurrency occurs, the system kernel state will need to continue to suspend the thread and restore the thread, frequent such operations will have a certain impact on the concurrency performance of our system. At the same time, smart JVM development teams have learned that locking up “shared resources” during application execution is extremely short, and that it can be “penny wise and pound foolish” to keep suspending and resuming threads just for that amount of time.

On a multi-core machine, multiple threads can be executed in parallel. If, instead of suspending the thread when a later thread does not acquire the lock, the thread continues to occupy the processor’s execution time, allowing the current thread to perform a busy loop (spin operation) that constantly watches to see if the thread holding the lock has released the lock, then this is a legendary spin lock.

Spin lock open

Although spin-locking was introduced in JDK1.4.2, it needs to be enabled with the “-xx :+UseSpinning” parameter. In JDK1.6, this is enabled by default. Let’s implement a simple version of spin lock based on CAS ourselves.


public class SimpleSpinningLock {

    /** * the thread that holds the lock. Null indicates that the lock is not held by the thread
    private AtomicReference<Thread> ref = new AtomicReference<>();

    public void lock(a){
        Thread currentThread = Thread.currentThread();
        while(! ref.compareAndSet(null, currentThread)){
            // compareAndSet returns true when ref is null, false otherwise
            // Determine whether the lock is held by another thread through a loop of constant spin}}public void unLock(a) {
        Thread cur = Thread.currentThread();
        if(ref.get() ! = cur){//exception ...
        }
        ref.set(null); }}Copy the code

Let’s test a crude spinlock implemented in just a few lines of code

public class TestLock {

    static int count  = 0;

    public static void main(String[] args) throws InterruptedException {
       ExecutorService executorService = Executors.newFixedThreadPool(100);
       CountDownLatch countDownLatch = new CountDownLatch(100);
       SimpleSpinningLock simpleSpinningLock = new SimpleSpinningLock();
       for (int i = 0 ; i < 100 ; i++){
           executorService.execute(new Runnable() {
               @Override
               public void run(a) { simpleSpinningLock.lock(); ++count; simpleSpinningLock.unLock(); countDownLatch.countDown(); }}); } countDownLatch.await(); System.out.println(count); }}// The lock function is implemented
Copy the code

As you can see from the above code, the spin is a loop to see if the condition is met, so what’s the problem? If the lock is held for a long time, the spin thread will also wait longer, wasting processor resources. So in the JDK, the default spin is 10 spins, which can be set with the argument “-xx :PreBlockSpin”. When this value is exceeded, the traditional thread suspension is used to wait for the lock to be released.

Adaptive spin lock

With an update to the JDK, in 1.6, there was something called “adaptive spin locking”. It makes spinning smarter than it used to be. “Adaptive” means that for the same lock object, the spin time of the thread is determined based on the spin time and state of the last thread that held the lock. For example, in the case of A lock object, if A thread has just spun to acquire the lock, and the thread is running, the JVM will consider the spin operation to have A good chance of getting the lock, so it will spin for A relatively long time. However, the JVM may even ignore the spin operation if the spin operation on the B-lock object is rarely successful. Therefore, adaptive spin lock is a much smarter, more business-friendly lock.

conclusion

Originally thought in an article to “spin lock”, “lock elimination”, “lock coarsening some lock” optimization are introduced, the concept of may be relatively large space, but found the little contact with this a classmate will be more difficult to understand, so I decided to separate multiple chapters introduce, hope you don’t understand the place to re-read it, slowly, I’m sure you’ll get something out of it.


Public account blog sync Github warehouse, interested friends can help give a Star oh, code word is not easy, thank you for your support.

Github.com/PeppaLittle…

Recommended reading

How to Optimize a lot of If /else, Switch/Case in code? How to Improve Efficiency with Java Reflection? How to Use Java Logging correctly

Follow the late Night programmer to share the driest stuff