synchronized底层的锁

本文探讨了Java中synchronized的偏向锁机制。在没有开启偏向锁时,对象会经历无锁、轻量级锁和重量级锁三个状态。而开启偏向锁后,通过设置-XX:BiasedLockingStartupDelay=0,对象可以更快地偏向于持有锁的线程,提高性能。未释放锁时,其他线程尝试获取会导致锁升级为轻量级或重量级状态。

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

偏向锁:大部分情况下,锁不仅仅不存在多线程竞争,而是总是由同一个线程多次获得,为了让线程获取锁的代价更低就引入了偏向锁。

没有开启偏向锁的情况下:

一个对象没有被作为锁对象,处于无锁状态

一个对象被一个线程获取作为锁对象,处于轻量级锁状态

一个线程已经持有了该锁对象,其他线程来争用,处于重量级锁状态

//没有开启偏向锁的情况

无锁状态
public class test {
	public static void main(String[] args) {
		A a=new A();
		String str = ClassLayout.parseInstance(a).toPrintable();//获取锁的状态
		System.out.println(str);
		//此时是无锁的状态
	}
}




轻量级锁状态
public class test {
    public static void main(String[] args) throws InterruptedException {
		A a=new A();
		String str = ClassLayout.parseInstance(a).toPrintable();//获取锁的状态
		System.out.println(str);
		//此时是无锁的状态
		
		new Thread() {
			public void run() {
				//把a作为锁对象
				synchronized(a) {
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			}
		}.start();
		
		Thread.sleep(10);//保证线程获取锁对象
		str = ClassLayout.parseInstance(a).toPrintable();//获取锁的状态
		System.out.println(str);//此时该锁的为轻量级锁
    }
}




重量级锁状态

public class test1{
	public static void main(String[] args) throws InterruptedException {
		A a=new A();
		String str = ClassLayout.parseInstance(a).toPrintable();//获取锁的状态
		System.out.println(str);
		//此时是无锁的状态
		
		new Thread() {
			public void run() {
				//把a作为锁对象
				synchronized(a) {
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			}
		}.start();
		
		Thread.sleep(10);//保证线程获取锁对象
		str = ClassLayout.parseInstance(a).toPrintable();//获取锁的状态
		System.out.println(str);//此时该锁的为轻量级锁
		
		//第二个线程
		new Thread() {
			public void run() {
				//把a作为锁对象
				synchronized(a) {
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			}
		}.start();
		Thread.sleep(10);//保证线程获取锁对象
		str = ClassLayout.parseInstance(a).toPrintable();//获取锁的状态
		System.out.println(str);//此时该锁的为重量级锁。
		//此时有两个线程,第一个线程已经获取了锁且没有释放锁,
		//第二个线程要尝试获取该锁
	}
}

class A{
	
}

开启偏向锁的情况下:

偏向锁的延迟时间的参数:-XX:BiasedLockingStartupDelay=0

一个对象没有被作为锁对象,处于无锁可偏向状态。(对象头中没有记录线程ID)

一个对象被一个线程作为锁对象,处于轻量级锁状态。(对象头中记录了线程ID)

一个对象被一个线程作为锁对象,释放锁对象后(但是该线程没有消亡时),其他线程再获取该锁对象,则处于轻量级锁状态

一个对象被一个线程作为锁对象,没有释放锁,其他线程也要获取该锁对象,就处于重量级锁状态

public class test {
	public static void main(String[] args) throws InterruptedException {
		A a=new A();
		String str = ClassLayout.parseInstance(a).toPrintable();//获取锁的状态
		System.out.println(str);
	}
}


public static void main(String[] args) throws InterruptedException {
		A a = new A();
		String str = ClassLayout.parseInstance(a).toPrintable();
		System.out.println(str);//101  无锁可偏向
		
		new Thread() {
			public void run() {
				synchronized(a) {
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				/*
				 * 	显示的让当前线程不结束
				 * 	如果结束了,下一个线程的id和刚才这个线程的id是一样的。
				 */
				try {
					Thread.sleep(100000000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}.start();
		Thread.sleep(100);
		str = ClassLayout.parseInstance(a).toPrintable();
		System.out.println(str);//101  无锁可偏向
		
		Thread.sleep(1000);//保证上一个线程已经把任务执行完毕了
		new Thread() {
			public void run() {
				synchronized(a) {
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
		Thread.sleep(100);
		str = ClassLayout.parseInstance(a).toPrintable();
		System.out.println(str);//
		
		new Thread() {
			public void run() {
				synchronized(a) {
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
		Thread.sleep(100);
		str = ClassLayout.parseInstance(a).toPrintable();
		System.out.println(str);//
	}
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值