尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

线程同步机制

线程同步机制
📅 发布时间:2026/6/19 1:41:01

并发:多个线程同时操作同一个对象
线程同步的形成条件:队列+锁

队列

处理多线程问题时,多个线程访问同一个对象,并且某些线程还想修改这个对象.这时候我们就需要线程同步.线程同步其实就是一种等待机制,多个需要同时访问比对象的线程进入这个对象的等待池形成队列,等待前面线程使用完毕,下一个线程再使用。

锁

由于同一进程的多个线程共享同一块存储空间,在带来方便的同时,也带来了访问冲突问题,为了保证数据在方法中被访问时的正确性,在访问时加入锁机制synchronized,当一个线程获得对象的排它锁,独占资源,其他线程必须等待,使用后释放锁即可·存在以下问题:

  • 一个线程持有锁会导致其他所有需要此锁的线程挂起;
  • 在多线程竞争下,加锁,释放锁会导致比较多的上下文切换和调度延时,引起性能问题;
  • 如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能问题.

三大不安全案例

// 不安全的买票
public class UnsafeBuyTicket {public static void main(String[] args) {BuyTicket station = new BuyTicket();Thread t1 = new Thread(station, "张三");Thread t2 = new Thread(station, "李四");Thread t3 = new Thread(station, "王五");t1.start();t2.start();t3.start();}
}class BuyTicket implements Runnable {private int ticket = 10;private boolean flag = true;// 买票public void buy() {if (ticket <= 0) {flag = false;return;}System.out.println(Thread.currentThread().getName()+"获得"+ticket--);}@Overridepublic void run() {while (flag) {buy();}}
}

PixPin_2025-11-03_09-11-44

在三人同时去车站买票这个例子中,可能出现两个人买到同一张票,或者一个人买到负数的票(两个人同时对ticket操作)
```java
public class UnsafeDrawing {public static void main(String[] args) {Account account = new Account("基金", 100);Drawing you = new Drawing(account, 50, "you");Drawing girl = new Drawing(account, 100, "girl");you.start();girl.start();}
}class Account {String name;int balance;public Account(String name, int balance) {this.name = name;this.balance = balance;}
}class Drawing extends Thread{Account account;int drawingMoney;int nowMoney = 0;public Drawing(Account account, int drawingMoney, String name) {super(name);this.account = account;this.drawingMoney = drawingMoney;}@Overridepublic void run() {if (account.balance < drawingMoney) {System.out.println(super.getName() + "余额不足");return;}try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}account.balance -= drawingMoney;nowMoney += drawingMoney;System.out.println(this.getName()+"取钱"+nowMoney);System.out.println(account.name+"余额为"+account.balance);}
}

PixPin_2025-11-03_08-33-52
这里同样是多个线程对同一用户对操作导致的线程不安全问题,中间我们加入了sleep来模拟网络延迟

public class UnsafeList {public static void main(String[] args) {List<String> list = new ArrayList<String>();for (int i = 0; i < 10000; i++) {new Thread(() -> {list.add(Thread.currentThread().getName());}).start();}System.out.println(list.size());}
}

在Java的标准库里,ArrayList是线程不安全的,Vector是线程安全的,可以在这个例子中看出
PixPin_2025-11-03_08-52-37

同步方法

一个实现线程同步的方法是加上synchornized修饰符,包含两种方法,synchornized方法与synchornized块;
这种实现方法的弊端就是不停地加锁释放锁非常浪费资源,所以只在需要进行写操作的时候加锁就好

注意:synchornized默认锁的是this,所以我们在第二个案例中,如果对run加锁锁住了Drawing对象,但是我们操作的account仍然被同时访问,导致存款为负数
我们可以使用同步块来制定锁住对象,如下

public void run() {synchronized (account) {if (account.balance < drawingMoney) {System.out.println(super.getName() + "余额不足");return;}try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}account.balance -= drawingMoney;nowMoney += drawingMoney;}System.out.println(this.getName()+"取钱"+nowMoney);System.out.println(account.name+"余额为"+account.balance);}

第三个案例同样如此

public class UnsafeList {public static void main(String[] args) {List<String> list = new ArrayList<String>();for (int i = 0; i < 10000; i++) {new Thread(() -> {synchronized (list) {list.add(Thread.currentThread().getName());}}).start();}System.out.println(list.size());}
}

CopyOnWriteArrayList

juc提供的一个安全的集合

import java.util.concurrent.CopyOnWriteArrayList;public class TestJUC {public static void main(String[] args) {CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();for (int i = 0; i < 10000; i++) {new Thread(()->{list.add(Thread.currentThread().getName());}).start();}System.out.println(list.size());}
}

相关新闻

  • 2025 年最新电缸源头厂家推荐排行榜:聚焦优质供应企业,助力企业精准选择传动元件合作伙伴同步带电缸/电动缸公司推荐
  • 这是一场豪赌
  • 2025年新疆高三复读班权威推荐榜单:高三集训班/高三冲刺班/高三复读全日制学校精选

最新新闻

  • 魔都黄金回收暗访实录:24小时上门实测闵行、浦东、松江、静安、普陀五家临街老店,谁才是最良心之选? - 昌福黄金回收
  • 思源宋体终极指南:7种字重免费开源字体解决你的中文排版难题
  • 深入解析S12 MSCAN模块:硬件保护、时钟配置与低功耗设计实战
  • 大模型转型攻略:小白程序员轻松入门,收藏这份从零到精通的学习指南!
  • MPC555/556微控制器架构解析:PowerPC内核、IMB总线与关键外设实战
  • ThumbmarkJS架构解析:从工厂模式到组件管理的设计哲学

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号