Java synchronization mechanism -synchronized use

synchronized Profile

Any object in the Java platform has an associated lock. Such locks are known as internal lock locks or monitored. Internal lock is an exclusive lock, it can guarantee atomicity, visibility and orderliness.

synchronized use

The method can be used to modify the synchronized keyword and code block, which has the following applications:

  • Common synchronization method, the lock is the current instance of the object class
  • Synchronous static method, the object lock is the class of the current class
  • Sync block, lock the object is inside the brackets

Synchronization common method

Synchronization common method, an object is an instance lock. We look at the situation without modification when Synchronized:

public class SynchronizedDemo {
    public void test(){
        for (int i = 0; i < 3; i++) {
            System.out.println("当前执行线程:" + Thread.currentThread().getName());
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        SynchronizedDemo sd = new SynchronizedDemo();
        new Thread(() -> {
            sd.test();
        }, "线程1").start();
        new Thread(() -> {
            sd.test();
        }, "线程2").start();
    }
}

Execution results are as follows:

当前执行线程:线程1
当前执行线程:线程2
当前执行线程:线程2
当前执行线程:线程1
当前执行线程:线程2
当前执行线程:线程1

We see no increase synchronization method, two threads can be executed simultaneously. We add synchronized modification method:

public synchronized void test(){
       for (int i = 0; i < 3; i++) {
           System.out.println("当前执行线程:" + Thread.currentThread().getName());
           try {
               Thread.sleep(200);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
}

Execution results are as follows:

当前执行线程:线程1
当前执行线程:线程1
当前执行线程:线程1
当前执行线程:线程2
当前执行线程:线程2
当前执行线程:线程2

You can see here, had a lock contention, the first to grab whoever executed, we need to note that when two threads call a method must be the same object. We look at the following situation:

public class SynchronizedDemo {
    public synchronized void test(){
        for (int i = 0; i < 3; i++) {
            System.out.println("当前执行线程:" + Thread.currentThread().getName());
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
    	// 实例对象sd1
        SynchronizedDemo sd1 = new SynchronizedDemo();
        // 实例对象sd2
        SynchronizedDemo sd2 = new SynchronizedDemo();
        new Thread(() -> {
        	// 调用实例sd1的方法
            sd1.test();
        }, "线程1").start();
        new Thread(() -> {
        	// 调用实例sd2的方法
            sd2.test();
        }, "线程2").start();
    }
}

Execution results are as follows:

当前执行线程:线程1
当前执行线程:线程2
当前执行线程:线程1
当前执行线程:线程2
当前执行线程:线程1
当前执行线程:线程2

Here, thread 1 and thread 2 are called different objects of the same class, so their competition is different locks, of course, can be executed myself at the same time.

Synchronous static method

Synchronous static method, the lock is a class object (Class Object). Here is a static method plus synchronized code:

public class SynchronizedDemo {
    public synchronized static void testStatic(){
        for (int i = 0; i < 3; i++) {
            System.out.println("当前执行线程:" + Thread.currentThread().getName());
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        SynchronizedDemo sd = new SynchronizedDemo();
        new Thread(() -> {
            sd.testStatic();
        }, "线程1").start();
        new Thread(() -> {
            sd.testStatic();
        }, "线程2").start();
    }
}

The results showed that the implementation of the synchronization to work, and we look at the situation at different instances of call:

public class SynchronizedDemo {
    public synchronized static void testStatic(){
        for (int i = 0; i < 3; i++) {
            System.out.println("当前执行线程:" + Thread.currentThread().getName());
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        // 实例对象sd1
        SynchronizedDemo sd1 = new SynchronizedDemo();
        // 实例对象sd2
        SynchronizedDemo sd2 = new SynchronizedDemo();
        new Thread(() -> {
            // 实例对象sd1的静态方法
            sd1.testStatic();
        }, "线程1").start();
        new Thread(() -> {
            // 实例对象sd2的静态方法
            sd2.testStatic();
        }, "线程2").start();
    }
}

Execution results are as follows:

当前执行线程:线程1
当前执行线程:线程1
当前执行线程:线程1
当前执行线程:线程2
当前执行线程:线程2
当前执行线程:线程2

While calling two threads here is an example of a different method, but do not forget, here is our lock class object (Class objects), it is clear here two instances belong to the same class of objects, so they need competing for the same lock.

Sync block

We look use synchronization code block:

public class SynchronizedDemo {
    public void test(){
        synchronized(this){
            for (int i = 0; i < 3; i++) {
                System.out.println("当前执行线程:" + Thread.currentThread().getName());
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) {
        SynchronizedDemo sd = new SynchronizedDemo();
        new Thread(() -> {
            sd.test();
        }, "线程1").start();
        new Thread(() -> {
            sd.test();
        }, "线程2").start();
    }
}

Execution results are as follows:

当前执行线程:线程1
当前执行线程:线程1
当前执行线程:线程1
当前执行线程:线程2
当前执行线程:线程2
当前执行线程:线程

We here used the synchronized (this), here, in fact, similar synchronization with the ordinary method, the current object is locked. Of course, we can also customize a lock object:

public class SynchronizedDemo {
    Object lock = new Object();
    public void test(){
        synchronized(lock){
            for (int i = 0; i < 3; i++) {
                System.out.println("当前执行线程:" + Thread.currentThread().getName());
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) {
        SynchronizedDemo sd = new SynchronizedDemo();
        new Thread(() -> {
            sd.test();
        }, "线程1").start();
        new Thread(() -> {
            sd.test();
        }, "线程2").start();
    }
}

The effect is the same:

当前执行线程:线程1
当前执行线程:线程1
当前执行线程:线程1
当前执行线程:线程2
当前执行线程:线程2
当前执行线程:线程2

synchronized usage summary

For synchronized, we summarized as follows:

  • For instance different objects of the same class, call them ordinary method (synchronized modification), because it is not the same lock, so no competition.
  • When you call a static method of the same class (synchronized modification), because it is the same lock (Class object class), it will compete.
  • When ordinary method (synchronized modification) a calling thread instance, if another thread calls its other ordinary asynchronous method does not need to acquire the lock can be executed simultaneously.
Released eight original articles · won praise 3 · Views 2213

Guess you like

Origin blog.csdn.net/ym572170/article/details/104799204