Synchronized使用的各种案例

本文详细介绍了Java中synchronized的使用,包括其保证原子性和可见性的原理,以及HotSpot虚拟机的实现方式,如偏向锁、自旋锁和重量级锁。文章通过多个实例展示了synchronized的不同用法,如锁定对象、this、Class对象,以及锁的重入性和异常处理。同时探讨了锁的选择,指出长时间运行和多线程场景适合重量级锁,而短时间运行的场景则适合轻量级锁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

synchronized: 锁定对象(在堆内存中),不能用String常量,Long,Integer 等基本类型;即保证了原子性又保证了可见性

原理
hotspot实现: hotspot是这样实现的,在一个对象的头64位,拿出2位来记录这个对象是否被锁定,并存入线程ID(mark word)
hotsport实现步骤
1.第一次 markword 记录这个线程ID,没有其他线程访问 (偏向锁
2.线程争用 (自旋锁)-用户空间,会占用CPU
其他线程争用,首先是自旋(理解为while循环心跳检测,超过10次升级为重量级锁)
3.升级为 (重量级锁)- 内核空间,不会占用CPU
重量级锁会去操作系统申请锁资源,经过OS,进入等待队列,不再占用CPU
注意:
1.锁一旦升级了,就不能降级
2.执行时间长的,线程数多,用重量级锁(系统锁)
3.执行时间短的(加锁代码),线程数少,用自选锁

实例一、sycnchronized锁定某个对象

//hotspot是这样实现的,在一个对象的头64位,拿出2位来记录这个对象是否被锁定(mark word)
   private int count = 10;
    Object o = new Object();
    public static void main(String[] args) {

    }
    private void syncTest(){
       synchronized (o){//任何线程要执行以下代码,都必须先拿到锁
           count --;
       }
    }

实例二、synchronized锁定this

private synchronized void syncTest(){
	count --;
}
等于
private void syncTest(){
	sychronized(this){
		count --;
	}
}

实例三、synchronized Class对象

private static synchronized void syncTest(){ //等价synchronized(Test.class)
	count --;
}

实例四:引用

Class T1{

private synchronized void m1(){
system.out.println("m1 start");
Thread.sleep(5000);
System.out.println("m1 end"); 
}
private void m2(){
system.out.println("m2 invoke");
}
public static void main(String[] args){
new Tread(t.m1);
new Thread(t.m2);
}

//print
//m1 start
//m2 invoke
//m1 end

}

实例五: 银行账号,写加锁,读不加锁,产生脏读
todo

实例六、锁可以重入
重入是针对同一个线程

private synchronized void m1(){
	m2();
};

private synchronized void m2(){
}

实例七、父子类锁重入

public class Parent{
	private synchronized void m(){
		System.out.println("this is parent");
	}
}

public class Child extends Parent{
	private synchronized void m(){
		System.out.println("this is child start");
		super.m();
		System.out.println("this is child end");
	}
}

实例八、异常会释放锁

private synchronized void m(){
	for(int i =0;i < 100; i ++){
		1/0; //异常释放锁
		...
	}
	
}

实例八:锁的细化

public void m(){
	count++;
	synchronized(this){
		...
	}
	...
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值