news 2026/8/18 0:18:24

Java多线程同步与互斥实现方法大揭秘!(面试必看)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java多线程同步与互斥实现方法大揭秘!(面试必看)

文章目录

  • Java多线程同步与互斥实现方法大揭秘!(面试必看)
    • 一、前言:多线程的那些事儿
    • 二、Java多线程同步与互斥的核心概念
    • 三、Java多线程同步与互斥的实现方法
      • 1. `synchronized`关键字:最简单的同步方式
        • 示例:用`synchronized`修饰方法
        • 示例:用`synchronized`修饰代码块
        • 优缺点分析:
      • 2. `ReentrantLock`:更灵活的同步工具
        • 示例:基本用法
        • 示例:可中断的锁
        • 优缺点分析:
      • 3. `Semaphore`:控制并发访问的数量
        • 示例:限制数据库连接数
        • 优缺点分析:
      • 4. `CountDownLatch`和`CyclicBarrier`:协调多线程执行
        • 示例:用`CountDownLatch`等待所有线程完成
        • 示例:用`CyclicBarrier`实现循环栅栏
        • 优缺点分析:
      • 5. `ReadWriteLock`:实现读写分离
        • 示例:用`ReentrantReadWriteLock`
        • 优缺点分析:
      • 6. `Atomic`类:无锁同步
        • 示例:用`AtomicInteger`
        • 优缺点分析:
      • 总结
    • 此外,合理的设计和清晰的代码结构也能帮助减少并发问题的发生。
      • 📚 领取 | 1000+ 套高质量面试题大合集(无套路,闫工带你飞一把)!

Java多线程同步与互斥实现方法大揭秘!(面试必看)

大家好,欢迎来到闫工的技术博客!今天我们要聊一个在Java开发中非常重要的话题——多线程同步与互斥的实现方法。作为一个Java工程师,掌握这部分知识是必不可少的,尤其是当你准备面试的时候,这个知识点几乎是必考的!所以,赶紧坐稳了,跟着闫工一起深入探讨一下。


一、前言:多线程的那些事儿

在聊同步与互斥之前,我们先来简单回顾一下Java中的多线程是什么。多线程是指在一个程序中同时运行多个执行路径的能力,这样可以提高程序的效率和响应速度。比如说,在一个网页应用中,主线程负责处理用户请求,而其他线程负责处理数据库查询、文件上传等任务,这样整个系统的性能就会更好。

但是,多线程编程有一个大坑——竞态条件(Race Condition)。当多个线程同时访问和修改共享资源时,就可能出现数据不一致或者程序崩溃的情况。举个例子,假设两个线程同时操作一个变量count,它们都试图将count加1,但结果可能因为执行顺序的问题导致count只增加了一次而不是两次。

所以,为了防止这种情况发生,我们需要使用同步和互斥机制来控制线程的执行顺序。接下来,我们就来看看Java中有哪些实现方法。


二、Java多线程同步与互斥的核心概念

在深入具体实现之前,我们先明确几个核心概念:

  1. 同步(Synchronization)
    同步是指在同一时间点上只能有一个线程执行某个代码块或方法。它的目的是为了防止多个线程同时操作共享资源,从而避免竞态条件的发生。

  2. 互斥(Mutex/Exclusive Access)
    互斥是一种更严格的同步机制,它确保在任何时刻只有一个线程可以访问某个资源或代码块。

  3. 临界区(Critical Section)
    临界区指的是那些需要被严格控制的共享资源访问区域。在这个区域内,必须实施同步和互斥机制。

了解了这些概念后,我们就可以开始探索具体的实现方法了。


三、Java多线程同步与互斥的实现方法

1.synchronized关键字:最简单的同步方式

synchronized是Java中最基础也是最常见的同步工具。它可以修饰方法或者代码块,确保在同一个时间点上只有一个线程可以执行被锁定的代码。

示例:用synchronized修饰方法
publicclassCounter{privateintcount=0;publicsynchronizedvoidincrement(){// 使用synchronized关键字修饰方法count++;}publicsynchronizedintgetCount(){returncount;}}
示例:用synchronized修饰代码块
publicclassAccount{privatedoublebalance;publicvoidwithdraw(doubleamount){synchronized(this){// 使用synchronized代码块if(balance>=amount){balance-=amount;}else{System.out.println("余额不足!");}}}publicvoiddeposit(doubleamount){synchronized(this){// 同一个锁对象,确保互斥balance+=amount;}}}
优缺点分析:
  • 优点:简单易用,语法清晰。
  • 缺点:只能实现简单的同步,无法支持复杂的同步需求(比如读写锁、超时等待等)。

2.ReentrantLock:更灵活的同步工具

如果synchronized关键字不能满足你的需求,那么Java并发包中的ReentrantLock就是更好的选择。它提供了更多的控制选项,比如公平锁、可中断锁等。

示例:基本用法
importjava.util.concurrent.locks.ReentrantLock;publicclassCounter{privateintcount=0;privateReentrantLocklock=newReentrantLock();publicvoidincrement()throwsInterruptedException{lock.lock();// 尝试获取锁,如果被占用则阻塞等待try{count++;}finally{lock.unlock();// 释放锁}}publicintgetCount()throwsInterruptedException{lock.lock();try{returncount;}finally{lock.unlock();}}}
示例:可中断的锁
publicclassInterruptibleLockExample{privateReentrantLocklock=newReentrantLock();publicvoiddoSomething()throwsInterruptedException{booleaninterrupted=false;while(!interrupted){try{lock.lockInterruptibly();// 可以响应中断的lock方法System.out.println("执行任务...");interrupted=true;}catch(InterruptedExceptione){System.out.println("被中断了,继续等待锁...");interrupted=false;}}}}
优缺点分析:
  • 优点:灵活性高,支持公平锁、可中断锁等高级特性。
  • 缺点:需要手动管理锁的获取和释放,增加了代码复杂度。

3.Semaphore:控制并发访问的数量

如果你的需求不是严格的互斥,而是希望同时允许一定数量的线程访问某个资源,那么Semaphore就是你的不二选择。它可以看作是一种“信号量”,用来控制同时可以执行某项操作的线程数量。

示例:限制数据库连接数
importjava.util.concurrent.Semaphore;publicclassDatabaseConnectionPool{privatestaticfinalintMAX_CONNECTIONS=5;privateSemaphoresemaphore=newSemaphore(MAX_CONNECTIONS);publicvoidgetConnection()throwsInterruptedException{semaphore.acquire();// 尝试获取信号量,如果不可用则阻塞等待try{System.out.println("成功获取数据库连接!");// 模拟使用连接的时间Thread.sleep(1000);}finally{semaphore.release();// 释放信号量System.out.println("已释放数据库连接!");}}publicstaticvoidmain(String[]args)throwsInterruptedException{DatabaseConnectionPoolpool=newDatabaseConnectionPool();for(inti=0;i<10;i++){Threadthread=newThread(()->{try{pool.getConnection();}catch(InterruptedExceptione){Thread.currentThread().interrupt();}});thread.start();// 适当延迟,让线程有机会交替执行Thread.sleep(50);}}}
优缺点分析:
  • 优点:能够灵活控制并发访问数量。
  • 缺点:实现相对复杂,需要理解信号量的工作原理。

4.CountDownLatchCyclicBarrier:协调多线程执行

有时候,我们需要在多个线程完成各自的任务后,再统一进行后续操作。这时候可以使用CountDownLatchCyclicBarrier来实现线程间的同步。

示例:用CountDownLatch等待所有线程完成
importjava.util.concurrent.CountDownLatch;publicclassCountDownLatchExample{publicstaticvoidmain(String[]args)throwsInterruptedException{intnumberOfThreads=5;CountDownLatchlatch=newCountDownLatch(numberOfThreads);for(inti=0;i<numberOfThreads;i++){Threadthread=newThread(()->{System.out.println("线程"+Thread.currentThread().getId()+"正在执行任务...");try{Thread.sleep(1000);}catch(InterruptedExceptione){Thread.currentThread().interrupt();}latch.countDown();// 通知计数器减一});thread.start();}// 等待所有线程完成latch.await();System.out.println("所有线程已完成任务!");}}
示例:用CyclicBarrier实现循环栅栏
importjava.util.concurrent.CyclicBarrier;publicclassCyclicBarrierExample{publicstaticvoidmain(String[]args)throwsInterruptedException{intnumberOfThreads=3;CyclicBarrierbarrier=newCyclicBarrier(numberOfThreads);for(inti=0;i<numberOfThreads;i++){Threadthread=newThread(()->{System.out.println("线程"+Thread.currentThread().getId()+"到达栅栏,等待其他线程...");try{barrier.await();}catch(InterruptedException|BrokenBarrierExceptione){// 处理异常}System.out.println("线程"+Thread.currentThread().getId()+"继续执行任务...");});thread.start();}}}
优缺点分析:
  • 优点:能够灵活地协调多个线程的执行顺序。
  • 缺点:需要正确配置和使用,否则可能导致死锁或其他问题。

5.ReadWriteLock:实现读写分离

在某些场景下,我们希望允许多个线程同时读取资源,但只允许一个线程写入资源。这时可以使用ReadWriteLock来实现读写分离的同步策略。

示例:用ReentrantReadWriteLock
importjava.util.concurrent.locks.ReentrantReadWriteLock;publicclassReadWriteLockExample{privateReentrantReadWriteLocklock=newReentrantReadWriteLock();privateintcount=0;publicvoidread()throwsInterruptedException{lock.readLock().lock();// 获取读锁try{System.out.println("线程"+Thread.currentThread().getId()+"正在读取数据,count="+count);}finally{lock.readLock().unlock();}}publicvoidwrite()throwsInterruptedException{lock.writeLock().lock();// 获取写锁try{System.out.println("线程"+Thread.currentThread().getId()+"正在写入数据...");count++;}finally{lock.writeLock().unlock();}}}
优缺点分析:
  • 优点:提高了读操作的吞吐量,适用于读多写少的场景。
  • 缺点:需要正确管理锁的获取和释放,否则可能导致性能问题。

6.Atomic类:无锁同步

如果你的场景只需要原子地修改某个变量,那么可以考虑使用Java内存模型中的Atomic类。它们通过CAS(Compare-and-Swap)操作实现无锁同步,性能非常高。

示例:用AtomicInteger
importjava.util.concurrent.atomic.AtomicInteger;publicclassAtomicIntegerExample{privateAtomicIntegercount=newAtomicInteger(0);publicvoidincrement(){// 原子地增加1,并返回新的值System.out.println("线程"+Thread.currentThread().getId()+"将count从"+(count.get())+"改为"+count.incrementAndGet());}publicstaticvoidmain(String[]args){AtomicIntegerExampleexample=newAtomicIntegerExample();for(inti=0;i<5;i++){Threadthread=newThread(example::increment);thread.start();}}}
优缺点分析:
  • 优点:性能极高,适用于简单的原子操作。
  • 缺点:只能处理单个变量的原子操作,无法处理复杂的同步逻辑。

总结

在Java中,线程间通信和共享数据需要谨慎处理以避免竞态条件、死锁和其他并发问题。选择合适的同步工具取决于具体的应用场景:

  • 简单的读写操作:考虑使用Atomic类。
  • 多线程协作:可以使用CountDownLatchCyclicBarrier
  • 读多写少的场景:适合使用ReadWriteLock
  • 需要协调多个任务完成顺序:可以考虑CompletableFuture
  • 复杂的同步需求:可能需要结合多种工具,或者自定义锁策略。

此外,合理的设计和清晰的代码结构也能帮助减少并发问题的发生。

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

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

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

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

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

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

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

基于springboot物流管理系统毕业论文+PPT(附源代码+演示视频)

文章目录基于springboot物流管理系统一、项目简介&#xff08;源代码在文末&#xff09;1.运行视频2.&#x1f680; 项目技术栈3.✅ 环境要求说明4.包含的文件列表&#xff08;含论文&#xff09;数据库结构与测试用例系统功能结构后台运行截图项目部署源码下载基于springboot物…

作者头像 李华
网站建设 2026/8/15 21:02:46

bugku——cookies(cookies欺骗)

打开之后是这样的是一些乱七八糟的字母也没有规律可言但是一眼就注意到了url中的?line&filenamea2V5cy50eHQ后面这个像一个base64&#xff0c;解码看看是keys.txt文件&#xff0c;如果是这样我们就知道了&#xff0c;想要访问某个文件必须是base64编码之后的&#xff0c;那…

作者头像 李华
网站建设 2026/8/17 19:06:15

【JavaWeb】乱码问题_GET请求参数乱码

GET请求乱码 GET请求方式乱码分析 GET方式提交参数的方式是将 编写如下servlet 使用表单方式提交参数 编写index.html 启动tomcat 此时并未出现乱码 如果修改如下编码方式为GBK 可以看到请求行中只有四个字节&#xff08;GBK中&#xff0c;一个汉字对应两个字节&#xff0…

作者头像 李华
网站建设 2026/8/17 13:39:49

节日贺卡设计:LobeChat生成温馨祝福语

节日贺卡设计&#xff1a;用 LobeChat 生成走心祝福语 在每年的节日季&#xff0c;写一张贺卡看似简单&#xff0c;却常常让人卡在第一句——“亲爱的”之后该接什么&#xff1f;是太正式显得生分&#xff0c;还是太随意少了仪式感&#xff1f;我们想要表达的情感很真&#xff…

作者头像 李华
网站建设 2026/8/17 20:01:55

LobeChat展览展示解说词创作

LobeChat&#xff1a;构建下一代AI交互的开源基石 在人工智能浪潮席卷各行各业的今天&#xff0c;大语言模型&#xff08;LLM&#xff09;的能力早已不再神秘。从GPT到Claude&#xff0c;再到各类开源模型&#xff0c;我们手握强大的“大脑”&#xff0c;但真正让这些智能落地、…

作者头像 李华
网站建设 2026/8/16 21:19:42

嘎嘎降免费1000字降AI,去aigc痕迹嘎嘎快!

市场上的降AI率工具良莠不齐&#xff0c;如何科学判断降AI率效果是很多学生、老师最关心的问题&#xff0c;担心降不来AI率&#xff0c;耽误时间还花不少钱。 本文将从以下五个维度系统&#xff0c;分析2025年主流的8个降AI工具&#xff0c;教大家如何选择适合自己的降AIGC工具…

作者头像 李华