多线程笔记(八):synchronized 锁的用法

synchronized修饰

  1.使用在静态方法上

public synchronized static void incr(){
    ...
}

  2.使用在方法中( ①对所有方法体加锁, ②对某个代码块加锁)

public void demo(){
    synchronized(this){
        ...
    }
}

synchronized作用域

 1.全局锁

//1.全局锁(加到 static 静态方法上的)
public synchronized static void incr(){
    ...
}

//2.全局锁(加到方法中,锁住的是当前类.class的)
public void demo(){
    synchronized(类.class){
        ...
    }
}  

2.当前对象锁

//1.当前对象锁(锁在方法上,锁住的是 this )
public void demo(){
    synchronized(this){
        ...		
    }
}

//实例↓↓↓
public static void main(String[] args){
    Demo demo01 = new Demo();
    demo01.demo();
				
    Demo demo02 = new Demo();
    demo02.demo();
    //demo01 和 demo02 之间的锁是互不影响的
}
			
public static void main(String[] args){
    Demo demo01 = new Demo();
    demo01.demo();
    demo01.demo();
    //这种情况下,同一实例多处调用,则会存在锁的等待
}

3.任何一个对象,都可以成为一把锁

   1.当前对象锁(lock不是一个静态的成员对象,那么这个时候,这种锁是实例级别

public class Demo{
    //定义了一把锁(当前对象锁)
    Object lock = new Object();

    public void demo(){
        synchronized(lock){
            ...				
        }
    }
    
    public static void main(String[] args){
        //main方法
    }
}

  2.全局锁(static修饰的 lock 锁,就是全局锁了

public class Demo{
    //定义了一把锁(全局锁)
    static Object lock = new Object();

    public void demo(){
        synchronized(lock){
            ...				
        }
    }
    
    public static void main(String[] args){
        //main方法
    }
}

简单原理

 1.synchronized 在 静态方法上

public synchronized static void incr(){
    ...
}

  字节码中, flags属性中,会增加一个:ACC_SYNCHRONIZED属性(如下图,图片来自网络,仅做部分了解)

 2.synchronized 在方法里面

public void demo(){
    synchronized(this){
        ...
    }
}

  字节码中,会增加两个指令:monitorenter
                                                 monitorexit

        

为什么会是有两个 monitorexit 呢?

        是这样的,编译器需要确保方法中调用过的每条 monitorenter 指令都要执行对应的 monitorexit 指令。为了保证在方法异常时,monitorenter 和 monitorexit 指令也能正常配对执行,编译器会自动产生一个异常处理器,它的目的就是用来执行异常的monitorexit 指令。而字节码中多出的 monitorexit 指令,就是异常结束时,被执行用来释放 monitor 的。

错误观点问题

 1.我听说 synchronized 是重量级锁,性能特别低是这样么?

       这句话不全对,JDK1.5以后对 synchronized 进行了大刀阔斧的优化,这其中涉及到自旋锁、偏向锁、轻量级锁、重量级锁、锁膨胀、锁消除等手段。


synchronized 锁的用法,介绍到此为止

如果本文对你有所帮助,那就给我点个赞呗 ^_^ 

End

发布了247 篇原创文章 · 获赞 44 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/lzb348110175/article/details/103668862