synchronized关键字的详解

基本使用

        Java中的synchronized关键字用于在多线程环境下确保数据同步。它可以用来修饰方法和代码块
当一个线程访问一个对象的synchronized方法或代码块时,其他线程将无法访问该对象的其他synchronized方法或代码块。这样可以确保在同一时间只有一个线程能够执行该代码块或方法,避免了多线程环境下的数据不一致问题,例如:

public class SynchronizedExample {
    private int count = 0;
    public synchronized void increment() {
        count++;
    }
}

         在上面的代码中,increment()方法是一个synchronized方法。当多个线程访问这个方法时,只有一个线程能够执行该方法的代码,其他线程将被阻塞
synchronized关键字也可以用来修饰代码块,如:

public void increment() {
    synchronized(this) {
        count++;
    }
}

        在上面的代码中,synchronized关键字修饰的是一个代码块,并且锁对象是当前对象(this)
注意:synchronized关键字会导致线程上下文切换和资源竞争,所以在使用时要注意性能问题

 

 源码解析

        底层实现是通过 Java 虚拟机(JVM)的对象头和监视器锁机制实现的

         具体来说,当一个线程访问一个对象的 synchronized 方法或代码块时,它会试图获取该对象的监视器锁。如果该锁未被其他线程占用,该线程将获得该锁并执行代码;如果该锁被其他线程占用,该线程将进入阻塞状态,等待获取该锁

        在Java中,每个对象都有一个与之关联的监视器锁,也称为内置锁对象锁。当线程进入一个synchronized方法或代码块时,它会尝试获取该对象的监视器锁。如果锁没有被其他线程占用,则该线程获得锁并开始执行代码;如果锁已经被其他线程占用,则该线程将被阻塞,直到锁被释放。

        在Java虚拟机中,每个对象头中都包含一部分用于实现synchronized的相关信息。这些信息包括:

  • mark word:用于存储对象的标记信息,包括锁的状态。
  • Klass pointer:指向对象的类元数据,包括synchronized的相关信息。
  • monitor:与对象关联的监视器,它记录了当前占用锁的线程、等待锁的线程队列等。

        当一个线程尝试获取一个对象的时,虚拟机会检查对象头中的标记信息。如果对象的锁状态为无锁状态,即未被其他线程占用,则该线程可以获取锁,并将标记信息设置为锁定状态

        如果对象的锁状态为已锁定,并且当前线程是锁的所有者,则该线程可以继续执行代码。如果对象的锁状态为已锁定,并且当前线程不是锁的所有者,则该线程将被放入等待队列中,进入阻塞状态

        当持有锁的线程执行完synchronized方法或代码块后,它会释放锁,即将对象头中的锁状态置为无锁状态,并唤醒等待队列中的一个线程,使其获取锁并继续执行。

        需要注意的是,synchronized关键字可以修饰方法和代码块。在方法上修饰的synchronized表示对整个方法进行同步,而在代码块上修饰的synchronized表示对该代码块进行同步,使用的锁对象通常是方法所属对象或指定的对象。

        总结起来,通过监视器锁的机制,Java的synchronized能够保证同一时刻只有一个线程访问同步代码块或方法,避免了多线程的数据竞争和并发问题。

        这里给出一份简化的 synchronized 关键字的源码: 

public void synchronized method() {
    // 加锁
    Monitor.enter(this);
    try {
        // 同步代码块
    } finally {
        // 释放锁
        Monitor.exit(this);
    }
}

         在这份代码中,方法通过调用 Monitor.enter 方法获取当前对象的监视器锁,并在 finally 块中调用 Monitor.exit 方法释放该锁。因此,在 synchronized 方法内部的代码可以保证在任意时刻只有一个线程可以访问

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值