news 2026/6/10 21:24:13

Java面试必懂!深入解析synchronized关键字的用法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java面试必懂!深入解析synchronized关键字的用法

文章目录

  • Java面试必懂!深入解析synchronized关键字的用法 ?
    • 一、什么是`synchronized`?
    • 二、`synchronized`的使用方式
      • 1. `synchronized`修饰实例方法
      • 2. `synchronized`修饰静态方法
      • 3. `synchronized`修饰代码块
      • 4. `synchronized`的关键点
    • 三、`synchronized`的优缺点
      • 优点
      • 缺点
    • 四、面试常见问题
      • 1. `synchronized`和`ReentrantLock`有什么区别?
      • 2. `synchronized`为什么会引起死锁?
      • 3. 如何避免死锁?
      • 4. `synchronized`和`volatile`有什么区别?
    • 五、实战案例
    • 六、总结
    • `
      • 📚 领取 | 1000+ 套高质量面试题大合集(无套路,闫工带你飞一把)!

Java面试必懂!深入解析synchronized关键字的用法 ?

大家好,我是闫工!今天呢,咱们来聊一个Java面试中绝对绕不开的话题——synchronized关键字。作为一个在Java世界里摸爬滚打多年的“老码农”,我得告诉你们,这个知识点可是线程安全领域的“老祖宗”了。不管是初学还是进阶,掌握它都是你通向高薪offer的必经之路!所以,咱们今天就从基础到高级,再到面试中可能会被问到的各种细节,来一场彻底的解析!


一、什么是synchronized

简单来说,synchronized关键字是用来保证线程安全的。在线程并发的情况下,多个线程同时操作共享资源时,容易出现“脏数据”或者“竞态条件”,这时候就需要用sync来加把锁,让代码块或方法变成“临界区”,每次只能有一个线程进入执行。

听起来有点抽象?没关系,咱们先来看一个经典的例子:银行转账问题。假设A和B两个人同时给C转账100元,那么如果不做任何处理,可能会出现这样的情况:

publicclassBank{privateintbalance=0;publicvoiddeposit(intamount){balance+=amount;// 这里可能有竞态条件!}publicstaticvoidmain(String[]args){Bankbank=newBank();Threadt1=newThread(()->bank.deposit(100));Threadt2=newThread(()->bank.deposit(100));t1.start();t2.start();}}

上面的代码中,deposit方法没有加锁,所以A和B可能同时读取到balance=0,然后都执行balance += 100,结果就是balance变成100而不是200。这就是线程不安全的表现。

那怎么解决呢?很简单,给deposit加上synchronized

publicsynchronizedvoiddeposit(intamount){balance+=amount;}

这样,每次只有一个线程能执行这个方法,问题就解决了!


二、synchronized的使用方式

1.synchronized修饰实例方法

这是最常见的用法。当一个实例方法被synchronized修饰时,锁的对象是调用该方法的那个具体实例(也就是this)。例如:

publicclassCounter{privateintcount=0;publicsynchronizedvoidincrement(){count++;}}

这样,在同一时间只有一个线程可以执行increment()方法。

2.synchronized修饰静态方法

有时候,我们需要对静态方法加锁。比如,一个类级别的计数器:

publicclassStaticCounter{privatestaticintcount=0;publicsynchronizedstaticvoidincrement(){count++;}}

这时候,锁的对象是这个类的Class对象(StaticCounter.class),所以不管有多少个实例,静态方法只有一个共享的锁。

3.synchronized修饰代码块

有时候我们不需要对整个方法加锁,只需要对一部分代码加锁。这时可以用synchronized包裹一个代码块:

publicclassThreadSafeBank{privateintbalance;publicvoidtransfer(intfromAccountId,inttoAccountId,intamount){synchronized(fromAccountId){// 锁住fromAccountId// 执行转账逻辑...}synchronized(toAccountId){// 锁住toAccountId// ...}}}

这样,可以更灵活地控制锁的范围。

4.synchronized的关键点

  • 锁的对象:无论是方法还是代码块,synchronized都是基于对象来加锁的。实例方法用this,静态方法用Class对象,代码块可以用任意对象。
  • 可重入性:同一个线程可以多次获取同一个锁,而不会死锁。比如,一个线程调用了synchronized方法A,然后在方法A里又调用了另一个synchronized方法B,这时候JVM会知道是同一线程,允许进入。

三、synchronized的优缺点

优点

  1. 简单直接:使用起来非常直观,几乎不需要额外配置。
  2. 内置支持:JDK原生支持,不需要引入第三方库。

缺点

  1. 性能问题:在高并发场景下,synchronized的粒度可能太大,导致线程 contention(争用),影响性能。
  2. 灵活性不足:只能提供粗粒度的锁控制,无法像ReentrantLock那样支持公平锁、可中断锁等高级特性。

四、面试常见问题

1.synchronizedReentrantLock有什么区别?

  • 语法层面synchronized是关键字,语法糖;而ReentrantLock是一个类,需要显式调用方法。
  • 功能层面ReentrantLock提供了更多的灵活性,比如支持公平锁、可中断锁等,但使用起来也更复杂。

2.synchronized为什么会引起死锁?

当两个线程互相等待对方释放锁时就会发生死锁。例如:

publicclassDeadlockExample{publicstaticvoidmain(String[]args){Threadt1=newThread(()->{synchronized(String.class){// 锁Atry{Thread.sleep(100);}catch(InterruptedExceptione){}synchronized(Integer.class){// 锁BSystem.out.println("Thread 1 done");}}});Threadt2=newThread(()->{synchronized(Integer.class){// 锁Btry{Thread.sleep(100);}catch(InterruptedExceptione){}synchronized(String.class){// 锁ASystem.out.println("Thread 2 done");}}});t1.start();t2.start();}}

如果t1先拿到锁A,而t2先拿到锁B,那么两个线程都会卡在等待对方释放锁的状态,导致死锁。

3. 如何避免死锁?

  • 按顺序加锁:所有线程都按照固定的顺序获取锁。
  • 使用tryLock()方法:如果无法立即获得锁,则不阻塞当前线程,而是返回一个布尔值表示是否成功。

4.synchronizedvolatile有什么区别?

  • 作用synchronized是关于多线程的互斥与同步;而volatile是关于内存可见性。
  • 粒度synchronized可以控制一段代码块或方法,而volatile只能修饰变量。

五、实战案例

假设我们有一个共享资源池,需要确保每次只有一个线程能获取资源。这时候可以用synchronized来实现:

publicclassResourcePool{privateObjectresource;publicsynchronizedvoidgetResource(){if(resource==null){// 模拟资源加载try{Thread.sleep(100);}catch(InterruptedExceptione){}resource=newObject();System.out.println("Resource created by "+Thread.currentThread().getName());}}publicstaticvoidmain(String[]args){ResourcePoolpool=newResourcePool();Runnabletask=()->pool.getResource();for(inti=0;i<10;i++){newThread(task,"Thread-"+i).start();}}}

这样,所有线程都会排队等待获取锁,从而保证资源只被创建一次。


六、总结

`

📚 领取 | 1000+ 套高质量面试题大合集(无套路,闫工带你飞一把)!

成体系的面试题,无论你是大佬还是小白,都需要一套JAVA体系的面试题,我已经上岸了!你也想上岸吗?

闫工精心准备了程序准备面试?想系统提升技术实力?闫工精心整理了1000+ 套涵盖前端、后端、算法、数据库、操作系统、网络、设计模式等方向的面试真题 + 详细解析,并附赠高频考点总结、简历模板、面经合集等实用资料!

✅ 覆盖大厂高频题型
✅ 按知识点分类,查漏补缺超方便
✅ 持续更新,助你拿下心仪 Offer!

📥免费领取👉 点击这里获取资料

已帮助数千位开发者成功上岸,下一个就是你!✨

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 19:39:49

无需NLP基础:用SiameseUniNLU轻松实现中文情感分类

无需NLP基础&#xff1a;用SiameseUniNLU轻松实现中文情感分类 你是否曾被“情感分析”“文本分类”这些词吓退&#xff1f;是否一看到“BERT微调”“损失函数”就关掉页面&#xff1f;别担心——今天这篇教程专为零NLP背景的开发者、运营、产品经理甚至市场同学设计。我们不讲…

作者头像 李华
网站建设 2026/6/10 11:44:26

手机照片秒变专业:RMBG-2.0轻量级抠图工具实测

手机照片秒变专业&#xff1a;RMBG-2.0轻量级抠图工具实测 你有没有过这样的经历&#xff1a;刚用手机拍完一组产品图&#xff0c;想发到小红书做种草笔记&#xff0c;结果背景杂乱、光线不均&#xff0c;修图软件调了半小时还是毛边明显&#xff1f;或者临时要交证件照&#…

作者头像 李华
网站建设 2026/6/10 15:10:13

基于微信小程序的四六级英语学习系统设计与实现

一、项目技术介绍 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/…

作者头像 李华
网站建设 2026/6/10 11:44:51

写作小白救星!千笔AI,自考论文写作神器

你是否曾为论文选题发愁&#xff0c;面对空白文档无从下手&#xff1f;是否在反复修改中感到力不从心&#xff0c;却始终无法达到理想效果&#xff1f;自考路上&#xff0c;论文写作是许多学生的“拦路虎”&#xff0c;选题难、框架乱、查重高、格式错……这些问题让人焦虑不已…

作者头像 李华