What synchronized locks

Time:2019-5-20

Preface

synchronizedTo translate into Chinese meansSynchronousIt isJavaKey words commonly used in thread security. Others call itSynchronous lock。 Since it is a lock, it must have something locked. Here’s a brief introduction.synchronizedAnd then it’s shown in an example codesynchronizedWhat’s locked? (Here’s the answer ahead of time.synchronizedThe lock is code.

introduce

Definition

synchronizedThe synchronization mechanism provided ensures thatAt the same time, only one thread executes the decorated block or method.

usage

synchronizedMethod and code blocks can be modified:

  1. Ordinary methods of modification
  2. Modifying static methods
  3. Modify code blocks

According to the modification, it can be divided into object locks and class locks.

  1. Object lock:

    • Common method (equivalent to code block modification)this
    • Code blocks embellish an object of a class
  2. Class lock

    • Class methods (equivalent to code blocks modifying the current class)ClassObject)
    • Code blocks embellish classesClassobject

principle

synchronizedThe underlying principle is that object holdings are usedmonitormonitor) But there is a difference between the principle of synchronization block and synchronization method.

  • Synchronized code blocks are usedmonitorenterandmonitorexitInstruction-implemented
  • Synchronization method is to read methods in the runtime constant pool by method call instructionsACC_SYNCHRONIZED Identity implements implicitly, but it’s actually calledmonitorenterandmonitorexitinstructions

Test example

Counter

A special counter, self-increasing methodincrease()coversynchronizedModify to get the current value methodgetCurrent()But not yet.synchronizedModification.

/**
 * counter
 * @author RJH
 * create at 2019-03-13
 */
public class Counter {
    /**
     * Global objects, total
     */
    private static int i = 0;

    /**
     * self increment
     * @return
     */
    public synchronized int increase() {
        try {
            // Use dormancy to make the results more obvious
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return ++i;
    }

    /**
     * Get the current value
     * @return
     */
    public int getCurrent() {
        return i;
    }
}

Test code

Verification using self-incremental threads and threads that get the current valuesynchronizedLocks are code, not global variables

/**
 * What synchronized locks
 * @author RJH
 * create at 2019-03-02
 */
public class LockWhatTest {

    public static void main(String[] args) {
        Counter counter =new Counter();
        IncreaseThread increaseThread1=new IncreaseThread(counter);
        IncreaseThread increaseThread2=new IncreaseThread(counter);
        GetThread getThread=new GetThread(counter);
        increaseThread1.start();
        increaseThread2.start();
        // The next step is not performed until the increaseThread thread starts
        while (increaseThread1.getState().compareTo(Thread.State.NEW)==0 && increaseThread1.getState().compareTo(Thread.State.NEW)==0){

        }
        getThread.start();
    }

    /**
     * Self-incremental Threads
     */
    static class IncreaseThread extends Thread{

        private Counter counter;

        public IncreaseThread(Counter counter) {
            this.counter = counter;
        }

        @Override
        public void run() {
            System.out.println("After increase:" + counter.increase()+",trigger time:"+System.currentTimeMillis());
        }
    }

    /**
     * Threads that get the current value
     */
    static class GetThread extends Thread{

        private Counter counter;

        public GetThread(Counter counter) {
            this.counter = counter;
        }

        @Override
        public void run() {
            System.out.println("Current:"+ counter.getCurrent()+",trigger time:"+System.currentTimeMillis());
        }
    }

}

results of enforcement

Current:0,trigger time:1552487003845
After increase:1,trigger time:1552487008846
After increase:2,trigger time:1552487013848

Result analysis

You can see from the test results.

  1. After two self-incrementing threads start, the threads that get the current value start, but the threads that get the current value are executed first.
  2. According to the time stamp interval of execution completion of self-incrementing threads, it can be seen that the two self-incrementing threads are executed sequentially.

Thus it can be proved.

  1. synchronizedNot locking variables accessed within a method
  2. synchronizedLocks the code monitored by the same monitor object