java 如何获取对象监视器

概述

java中每个对象都有一个对象监视器,对象监视器如同一把锁,具有排他性、独占性,如果线程A获取到对象监视器,则其它线程不能再对此对象进行操作,直到线程释放对象监视器。

那么如何获取对象监视器呢?援引how to own the objects monitor

A thread becomes the owner of the object’s monitor in one of three
ways:
By executing a synchronized instance method of that object.
By executing the body of a synchronized statement that synchronizes on the object.
For objects of type Class, by executing a synchronized static method of that class.

翻译过来就是
- 执行synchronized的object实例方法
- 执行synchronized(object)的同步代码块
- 对于Class类型的对象,执行这个类的静态方法

验证

下边我们将一一验证

执行synchronized的object实例方法

public class TestSynchronizedMethod {

    public synchronized void  m1(){
        System.out.println(System.currentTimeMillis()+" m1 method.....");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public synchronized void  m2(){
        System.out.println(System.currentTimeMillis()+" m2 method.....");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public void m3(){
        System.out.println(System.currentTimeMillis()+" m3 method.....");
    }

    public static void main(String[] args) {
        TestSynchronizedMethod testSynchronizedMethod = new TestSynchronizedMethod();
        new Thread(new Runnable() {
            @Override
            public void run() {

                testSynchronizedMethod.m1();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {

                testSynchronizedMethod.m2();
            }
        }).start();

        testSynchronizedMethod.m3();

    }
}

输出结果

1576832098171 m3 method.....
1576832098171 m1 method.....
1576832103172 m2 method.....

1576832098171 -1576832103172 =5s,大约5秒后,m1释放锁后,m2才得以执行。注意因为m3未加synchronized所以不受锁影响,可并行执行。

执行synchronized的同步代码块

本种方法有点类似上一种,只是synchronized(object),object是个实例对象。

public class TestSynchronizedMethod {
    private Object lock;

    public TestSynchronizedMethod(Object lock){
        this.lock = lock;
    }
    public  void  m1(){
        synchronized (lock){
            System.out.println(System.currentTimeMillis()+" m1 method.....");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
    public  void  m2(){
        synchronized (lock){
            System.out.println(System.currentTimeMillis()+" m2 method.....");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }



    public static void main(String[] args) {
        TestSynchronizedMethod testSynchronizedMethod = new TestSynchronizedMethod(new Object());
        new Thread(new Runnable() {
            @Override
            public void run() {

                testSynchronizedMethod.m1();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {

                testSynchronizedMethod.m2();
            }
        }).start();


    }
}

输出结果

1576832699302 m1 method.....
1576832704303 m2 method.....

同样,只有m1释放锁后,m2才得以执行。

对于Class类型的对象,执行synchronized类的静态方法

public class TestSynchronizedMethod {



    public synchronized  static void  m1(){

            System.out.println(System.currentTimeMillis()+" m1 method.....");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


    }
    public synchronized  static void  m2(){

            System.out.println(System.currentTimeMillis()+" m2 method.....");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

    }

    public synchronized void m3(){
        System.out.println(System.currentTimeMillis()+" m3 method.....");
    }



    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override
            public void run() {

                TestSynchronizedMethod.m1();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {

                TestSynchronizedMethod.m2();
            }
        }).start();
        TestSynchronizedMethod testSynchronizedMethod = new TestSynchronizedMethod();
        testSynchronizedMethod.m3();

    }
}

输出结果

1576833370592 m1 method.....
1576833370593 m3 method.....
1576833375594 m2 method.....

可以看到,m1执行5秒后,m2才得以执行。虽然m3也是synchronized,但并不妨碍,也是因为m1、m2锁定的对象是TestSynchronizedMethod .class,而m3锁定的对象是testSynchronizedMethod ,锁定的不是同一个对象,所以互不影响。
经常会有人说,如果synchronized static方法,那么实例方法不能执行,这种说法是错误的!

总结

获取对象监视器,要是用synchronized关键字,synchronized方法之间是否影响要看,锁定的对象是否是同一个。

发布了336 篇原创文章 · 获赞 369 · 访问量 193万+

猜你喜欢

转载自blog.csdn.net/wangjun5159/article/details/103725942