synchronized之锁浅析

前言

废话少说,主要是弄清楚概念上的东西,方便在写程序中实际运用。

锁的分类

对象锁:synchronized修饰具体的类的实例对象,或者修饰类的一个方法
方法锁:synchronized修饰类的一个方法
类锁:synchronized修饰一个类的静态方法,或者修饰诸如(Object.class)

具体的代码

对象锁

修饰具体的类的实例对象

public class Test {
    public void method(){
        synchronized(this){
            System.out.println("我是对象锁");
        }
    }
}

也可以这么写

public class Test{
    private Test test=new Test();
    public void method(){
        synchronized(test){
            System.out.println("我是对象锁");
        }
    }
}

修饰类的一个方法时

public class Test{
    public synchronized void method(){
        System.out.println("我是对象锁也是方法锁");
    }
}

方法锁

上面已经提到了,如下

public class Test{
    public synchronized void method(){
        System.out.println("我是方法锁也是对象锁");
    }
}

类锁

public class Test{
    public void method(){
        synchronized(Test.class){
            System.out.println("我是类锁");
        }
    }
}

修饰类的静态方法时

public class Test{
    public synchronized static void method(){
        System.out.println("我是类锁");
    }
}

至于为什么锁静态方法就是类锁,稍作解释:
因为一个方法被定义为静态之后,那么该方法就属于这个类,而不是类的实例,在内存中也只有一份,我把这个仅有的一份锁住了,其它要调用的只能去请求锁,从而实现锁类。

我之前的小疑问

关于锁这里,我之前一直有个疑问:为什么一般的操作都是锁类,锁实例对象,或者锁方法,为啥不锁类的成员变量呢?

我现在的理解是:既然我锁成员变量,肯定希望这个成员变量不被两个线程同时更改造成不同步的问题,但是这个问题完全可以由锁对象实例来解决,而且锁对象实例范围更加大一点,这个对象实例的所有成员变量的操作都是同步的,其实锁类也可以,只不过锁类只能锁静态成员变量。

关于这个小疑问,可能我的理解有失偏颇,还望不吝赐教!

后来补充:关于上面这个疑问,看到有的文章解释的比较详细,给出的理由是:实例变量和类变量本身就不持有锁,所以无法对其进行加锁。

然后关于这三种锁的作用,方法锁我=就不用赘述了,类锁和对象锁的作用:
对象锁是用来控制实例方法之间的同步,类锁是用来控制静态方法(或静态变量互斥体)之间的同步
方法锁(非静态方法)其实也可以理解为对象锁,因为要访问synchronized修饰的方法,要获得对象锁才行

一些易错的地方

关于对象锁这里,如果是锁的两个不同的类对象实例,二者是不会同步的,因为我们所说的对象锁,只是针对同一个实例对象,如果是两个不同的实例对象,不会具有竞争关系。说简单点就是,多个对象会有多个锁,互不干扰。

结语

暂时到这,实际使用如果有什么问题,再拿来这里结合分析。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章