(1) Runtime classes

The runtime class has only one copy in memory, thread synchronization.

package com.southwind.thread;

public class SynchronizedTest {
        public static void main(String[] args) {
            MyRunnable myRunnable = new MyRunnable();
            for (int i = 1; i <= 5; i++) {
              new Thread(myRunnable,"Thread"+i).start();
            }
          }
        }

class MyRunnable implements Runnable{
          private int num = 0;
          @Override
          public void run() {
            // TODO Auto-generated method stub
            synchronized (MyRunnable.class) {
                          num++;
              try {
                Thread.currentThread().sleep(100);
              } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                      }
              System.out.println(Thread.currentThread().getName()+"Is the first"+num+"A visitor."); }}}Copy the code


The running results are shown in the figure.



(2) Instance object

Instance object creation is written outside of the for loop, so there is only one instance object in memory and the thread synchronizes.

package com.southwind.thread;

public class SynchronizedTest {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        for (int i = 1; i <= 5; i++) {
            new Thread(myRunnable,"Thread"+i).start();
        }
    }
}

class MyRunnable implements Runnable{
    private int num = 0;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        synchronized (this) {
            num++;
            try {
                Thread.currentThread().sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"Is the first"+num+"A visitor."); }}}Copy the code

The running results are shown in the figure.



The creation of instance objects is written inside the for loop, so there are multiple instance objects in memory and the thread is asynchronous.

package com.southwind.thread;

public class SynchronizedTest {
    public static void main(String[] args) {
        for (int i = 1; i <= 5; i++) {
            MyRunnable myRunnable = new MyRunnable();
            new Thread(myRunnable,"Thread"+i).start();
        }
    }
}

class MyRunnable implements Runnable{
    private int num = 0;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        synchronized (this) {
            num++;
            try {
                Thread.currentThread().sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"Is the first"+num+"A visitor."); }}}Copy the code

The running results are shown in the figure.



(2.1) Instance object



(3) Member variables

The number of member variables in memory is determined by calling equals(). If equals() returns true, two variables are equal and there is only one copy in memory. If equals() returns false, two variables are not equal and there are multiple copies in memory.

package com.southwind.thread;

public class SynchronizedTest {
    public static void main(String[] args) {
        Object obj = new Object();
        MyRunnable myRunnable = new MyRunnable(obj);
        Object o1 = myRunnable.obj;
        for (int i = 1; i <= 5; i++) {
            myRunnable.obj = new Object();
            System.out.println(myRunnable.obj.equals(o1));
            o1 = myRunnable.obj;
            new Thread(myRunnable,"Thread"+i).start();
        }
    }
}

class MyRunnable implements Runnable{
    private int num = 0;
    public Object obj;
    public MyRunnable(Object obj) {
        // TODO Auto-generated constructor stub
        this.obj = obj;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        synchronized (obj) {
            num++;
            try {
                Thread.currentThread().sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"Is the first"+num+"A visitor."); }}}Copy the code

MyRunnable’s member variable obj is re-assigned each time the thread object is created through the loop, so the member variables are multiple, equals returns false, and the thread is asynchronous.

The running results are shown in the figure.

A little…

Myrunnable.obj = new Object();

package com.southwind.thread;

public class SynchronizedTest {
    public static void main(String[] args) {
        Object obj = new Object();
        MyRunnable myRunnable = new MyRunnable(obj);
        Object o1 = myRunnable.obj;
        for (int i = 1; i <= 5; i++) {
            System.out.println(myRunnable.obj.equals(o1));
            o1 = myRunnable.obj;
            new Thread(myRunnable,"Thread"+i).start();
        }
    }
}

class MyRunnable implements Runnable{
    private int num = 0;
    public Object obj;
    public MyRunnable(Object obj) {
        // TODO Auto-generated constructor stub
        this.obj = obj;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        synchronized (obj) {
            num++;
            try {
                Thread.currentThread().sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"Is the first"+num+"A visitor."); }}}Copy the code

The member variable obj of MyRunnable is not reassigned each time the thread object is created through the loop, so the member variable is an equals method that returns true, and the thread synchronizes.

The running results are shown in the figure.



Reference source: https://cloud.tencent.com/developer/article/1355674


The following reference: https://www.bilibili.com/video/av45946533/?p=31

(4) Static methods lock all object instance callers of the class

package com.mmall.practice.example.sync; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @slf4j public class SynchronizedExample2 {SynchronizedExample2 public class SynchronizedExample2 public static synchronized void SynchronizedExample2test1() {

        for (int i = 0; i < 10; i++) {
            log.info("test1 - {}", i); }} // modifies a class whose scope is the parenthesized part of synchronized, and whose main objects are all objects of that class. public static voidtest2() {

        synchronized (SynchronizedExample2.class) {

            for (int i = 0; i < 10; i++) {
                log.info("test2 - {}", i);
            }
        }
    }

    public static void main(String[] args) {
        SynchronizedExample2 example1 = new SynchronizedExample2();
        SynchronizedExample2 example2 = new SynchronizedExample2();
        ExecutorService exec = Executors.newCachedThreadPool();
       // public static synchronized void testExample1, example2 // example1.test1(); And example2 test1 (); Exec.execute (() -> {try {example1.test1(); } catch (Exception e) { log.error("exception1", e); }}); exec.execute(() -> { try { example2.test1(); } catch (Exception e) { log.error("exception2", e); }}); / / synchronized (SynchronizedExample2. Class) the scope of its role is the static method, lock object is an object of this class all example1, example2 exec.execute(() -> { try { example1.test2(); } catch (Exception e) { log.error("exception1", e); }}); exec.execute(() -> { try { example2.test2(); } catch (Exception e) { log.error("exception2", e); }}); exec.shutdown(); }}Copy the code