如果synchronized锁住一个对象的不同变量或办法,会造成竞态条件吗?synchronized背地的原理是什么?

先看一个试验:

//别离尝试去锁一个对象的成员变量,成员办法,动态变量,静态方法,//class对象以及对象自身,哪些操作会造成动态条件?public class TestObj {    private String field1 = "123";    private static String field2 = "456";    private String field3;    private String field4;    public void normalMethod() {        Date date = new Date();        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        String time = format.format(date);        System.out.println(time+":一般办法");        try {            Thread.sleep(5000);            System.out.println(format.format(new Date())+":"+Thread.currentThread().getName());        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public synchronized void lockMethod() {        Date date = new Date();        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        String time = format.format(date);        System.out.println(time+":锁定一般办法");        try {            Thread.sleep(5000);            System.out.println(format.format(new Date())+":"+Thread.currentThread().getName());        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public static synchronized void lockStaticMethod() {        Date date = new Date();        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        String time = format.format(date);        System.out.println(time+":锁定静态方法");        try {            Thread.sleep(5000);            System.out.println(format.format(new Date())+":"+Thread.currentThread().getName());        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public void lockField() {        synchronized (field1) {            Date date = new Date();            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");            String time = format.format(date);            System.out.println(time+":锁定一般变量");            try {                Thread.sleep(5000);                System.out.println(format.format(new Date())+":"+Thread.currentThread().getName());            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public void lockStaticField() {        synchronized (field2) {            Date date = new Date();            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");            String time = format.format(date);            System.out.println(time+":锁定动态变量");            try {                Thread.sleep(5000);                System.out.println(format.format(new Date())+":"+Thread.currentThread().getName());            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public void lockStaticClass() {        synchronized (TestObj.class) {            Date date = new Date();            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");            String time = format.format(date);            System.out.println(time+":锁定class对象");            try {                Thread.sleep(5000);                System.out.println(format.format(new Date())+":"+Thread.currentThread().getName());            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public void normalField() {        Date date = new Date();        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        String time = format.format(date);        System.out.println(time+":一般字段:"+field1);        try {            Thread.sleep(5000);            System.out.println(format.format(new Date())+":"+Thread.currentThread().getName());        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
public class Main {    public static void main(String[] args) {        TestObj obj = new TestObj();        Thread thread1 = new Thread(() -> {            obj.lockStaticField();        }, "1");        Thread thread2 = new Thread(() -> {            obj.lockStaticClass();        }, "2");        Thread thread8 = new Thread(() -> {            TestObj.lockStaticMethod();        }, "8");        Thread thread3 = new Thread(() -> {            obj.lockMethod();        }, "3");        Thread thread4 = new Thread(() -> {            obj.lockField();        }, "4");        Thread thread5 = new Thread(() -> {            obj.normalMethod();        }, "5");        Thread thread6 = new Thread(() -> {            obj.normalField();        }, "6");        Thread thread7 = new Thread(() -> {            synchronized (obj) {                Date date = new Date();                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");                String time = format.format(date);                System.out.println(time + ":锁定一般对象");                try {                    Thread.sleep(5000);                    System.out.println(format.format(new Date()) + ":" + Thread.currentThread().getName());                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }, "7");        thread1.start();        thread2.start();        thread3.start();        thread4.start();        thread5.start();        thread6.start();        thread7.start();        thread8.start();    }}

颁布答案:

2021-06-04 13:29:41:锁定class对象2021-06-04 13:29:41:一般办法2021-06-04 13:29:41:一般字段:1232021-06-04 13:29:41:锁定一般办法2021-06-04 13:29:41:锁定动态变量2021-06-04 13:29:41:锁定一般变量2021-06-04 13:29:46:62021-06-04 13:29:46:22021-06-04 13:29:46:12021-06-04 13:29:46:42021-06-04 13:29:46:32021-06-04 13:29:46:52021-06-04 13:29:46:锁定静态方法2021-06-04 13:29:46:锁定一般对象2021-06-04 13:29:51:82021-06-04 13:29:51:7

重复尝试,发现可见锁静态方法会与锁class对象造成竞态条件,锁一般办法会与锁一般对象造成竞态条件

//todo