synchronized的JVM底层原理。

一、原理

synchronized关键字是Java中用于实现线程同步的重要机制,它可以确保多个线程对共享资源的安全访问。在JVM底层,synchronized的实现涉及到对象头(Object Header)monitor对象监视器等概念。

当一个线程进入synchronized代码块时,会尝试获取对象的monitor对象监视器,如果对象的monitor对象尚未被锁定,线程会成功获取锁并继续执行;如果对象的monitor对象已经被其他线程锁定,当前线程会进入阻塞状态等待锁释放。

在JVM底层,每个Java对象都会有一个与之关联的monitor对象,monitor对象包含了锁的信息、持有锁的线程、等待队列等。当一个线程获取了对象的monitor对象锁时,会在monitor对象上记录持有锁的线程,并将锁计数器加一;其他线程尝试获取锁时,会进入等待队列等待锁释放。

在JVM中,synchronized关键字的底层实现是通过monitorentermonitorexit两条指令来实现的。当进入synchronized代码块时,会执行monitorenter指令来尝试获取对象的monitor对象锁;当退出synchronized代码块时,会执行monitorexit指令来释放对象的monitor对象锁。

二、synchronized代码如下

public class SynchronizedExample extends Thread{

    public static void main(String[] args) {
        new  SynchronizedExample().start();
    }

	public void run() {
			test();
		}

   public void test() {
	
            synchronized (this) {
                System.out.println("Thread 1 acquired the lock");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println("Thread 1 released the lock");
            }
        
	}
}
  

上面代码中创建了两个线程 thread1 和 thread2 ,它们都尝试使用相同的 lock 对象进行同步。当 thread1 获取了 lock 对象的monitor对象锁时, thread2 尝试获取锁时会被阻塞,直到 thread1 释放锁后才能获取锁。

三、使用javap反编译查看原理

javap -c SynchronizedExample

使用javap可以的到类对应的字节码指令

Compiled from "SynchronizedExample.java"
public class SynchronizedExample extends java.lang.Thread {
  public SynchronizedExample();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Thread."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class SynchronizedExample
       3: dup
       4: invokespecial #3                  // Method "<init>":()V
       7: invokevirtual #4                  // Method start:()V
      10: return

  public void run();
    Code:
       0: aload_0
       1: invokevirtual #5                  // Method test:()V
       4: return

  public void test();
    Code:
       0: aload_0
       1: dup
       2: astore_1
       3: monitorenter
       4: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
       7: ldc           #7                  // String Thread 1 acquired the lock
       9: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      12: ldc2_w        #9                  // long 2000l
      15: invokestatic  #11                 // Method java/lang/Thread.sleep:(J)V
      18: goto          28
      21: astore_2
      22: invokestatic  #13                 // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
      25: invokevirtual #14                 // Method java/lang/Thread.interrupt:()V
      28: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
      31: ldc           #15                 // String Thread 1 released the lock
      33: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      36: aload_1
      37: monitorexit
      38: goto          46
      41: astore_3
      42: aload_1
      43: monitorexit
      44: aload_3
      45: athrow
      46: return
    Exception table:
       from    to  target type
          12    18    21   Class java/lang/InterruptedException
           4    38    41   any
          41    44    41   any
}


  • 14
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值