高频面试题:再谈Synchronized实现原理!

本文详细探讨了Java中的Synchronized关键字,包括其用法、实现原理和锁优化。Synchronized用于保证线程安全,确保在同一时刻只有一个线程可以执行特定代码。文章介绍了对象锁、类锁、同步代码块和同步方法的使用,以及Synchronized的优化如自旋锁、偏向锁和轻量级锁。同时,文章还分析了Synchronized的底层实现,涉及对象头的Mark Word和Monitor对象。最后,文章列举了一些常见的面试题,帮助读者巩固Synchronized的知识。
摘要由CSDN通过智能技术生成

前言

线程安全是并发编程中的重要关注点。

造成线程安全问题的主要诱因有两点,一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据。

为了解决这个问题,我们可能需要这样一个方案,当存在多个线程操作共享数据时,需要保证同一时刻有且只有一个线程在操作共享数据,其他线程必须等到该线程处理完数据后再进行。

在 Java 中,关键字 Synchronized可以保证在同一个时刻,只有一个线程可以执行某个方法或者某个代码块(主要是对方法或者代码块中存在共享数据的操作)。

下面来一起探索Synchronized的基本使用、实现机制。

用法

两类锁:

对象锁:包括方法锁(默认锁对象为this当前实例对象)和同步代码块锁(自己指定锁对象)。

类锁:指Synchronized修饰静态的方法或指定锁为Class对象。

当一个线程试图访问同步代码块时,它首先必须得到锁,而退出或抛出异常时必须释放锁。

  • 给普通方法加锁时,上锁的对象是 this;

  • 给静态方法加锁时,锁的是 class 对象;

  • 给代码块加锁,可以指定一个具体的对象作为锁。

代码示例如下:

public class SynchronizedTest {

    /**
     * 修饰静态方法, 等同于下面注释的方法
     */
    public synchronized static void test1() {
        System.out.println("月伴飞鱼");
    }


//    public static void test1() {
//        synchronized (SynchronizedTest.class){
//            System.out.println("月伴飞鱼");
//        }
//    }


    /**
     * 修饰实例方法, 等同于下面注释的方法
     */
    public synchronized void test2(){
        System.out.println("月伴飞鱼");
    }

//    public void test2(){
//        synchronized (this){
//            System.out.println("月伴飞鱼");
//        }
//    }

    /**
     * 修饰代码块
     */
    public void test3(){
        synchronized (this){
            System.out.println("月伴飞鱼");
        }
    }

}

多线程访问同步方法的几种情况:

两个线程同时访问一个对象的同步方法。

由于同步方法锁使用的是this对象锁,同一个对象的this锁只有一把,两个线程同一时间只能有一个线程持有该锁,所以该方法将会串行运行。

两个线程访问的是两个对象的同步方法。

由于两个对象的this锁互不影响,Synchronized将不会起作用,所以该方法将会并行运行。

两个线程访问的是Synchronized的静态方法。

Synchronized修饰的静态方法获取的是当前类模板对象的锁,该锁只有一把,无论访问多少个该类对象的方法,都将串行执行。

同时访问同步方法与非同步方法

非同步方法不受影响。

访问同一个对象的不同的普通同步方法。

由于this对象锁只有一个,不同线程访问多个普通同步方法将串行运行。

同时访问静态Synchronized和非静态Synchronized方法

静态Synchronized方法的锁为class对象的锁,非静态Synchronized方法锁为this的锁,它们不是同一个锁,所以它们将并行运行。

使用优化

大家在使用synchronized关键字的时候ÿ

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值