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方法之间是否影响要看,锁定的对象是否是同一个。

    原文作者:QQ_851228082
    原文地址: https://blog.csdn.net/wangjun5159/article/details/103725942
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞