给当前对象加锁,改变对象头信息,由于synchronized底层做了优化加锁过程,不会立即变成重量锁,而是从偏向锁慢慢膨胀轻量锁,再到重量锁。重量锁就是synchronized是一个指令,解析成monitener,然后jvm去执行。 synchronized同步代码块,通过monitorenter和monitorexit指令,monitorenter指令指向同步代码块的开始同步的位置,monitorexit指令指向同步代码块的结束同步的位置。当执行monitorenter指令时,线程会试图获取monitor的持有权,也就是加锁。每个java对象都包含有一个monitor监视器(synchronized锁便是通过这种方式获取锁)。内部包含一个计数器,monitorenter执行时,当计数器为0则成功获取,获取之后会将计数器设置为1。相应的执行monitorexit后,会将锁变为0,表示释放锁。如果获取对象锁失败,那么当前线程就会阻塞等待,直到锁被其他线程释放。 但是,synchronized修饰的方法并没有monitorenter和monitorexit指令,取而代之的是“ACC_synchronized”标识,该标识指明该方法为同步方法,JVM通过这个标识来识别,进而进行同步。
synchronized是一个指令,解析成monitener,然后JVM去执行 改变对象头信息。在JVM中,每个对象都有一个内部锁或监视器锁,当一个线程进入一个synchronized块或方法时,它需要获取该对象的内部锁。如果锁已经被其他线程持有,那么该线程会被阻塞,直到锁被释放。在JVM中,每个对象都有一个内部锁或监视器锁,当一个线程进入一个synchronized块或方法时,它需要获取该对象的内部锁。
对象状态:无锁、偏向锁、轻量锁、重量锁、gc标记,只有锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁,如图所示。对象头的最后三位控制对象的5种状态
对象synchronized加锁,一把锁,在没有竞争的情况下,被同一个对象多次获取,所以没必要一直加锁操作,以此来减少CPU资源,所以就会导致加了锁,最后三位数还是000。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。