java线程同步
创始人
2025-05-30 21:47:27
  • 并发:同一个对象被多个线程同时操作
  • 处理多线程问题时,多个线程访问同一个对象,并且某些线程还想修改这个对象,这时候我们就需要线程同步,线程同步其实就是一种等待机制,多个线程需要访问同一个对象的线程进入这个对象的等待池形成队列,等待前一个线程使用完毕,下一个线程再使用、
  • 线程同步现形成条件:队列和锁
  • 由于同一个进程的多个线程共享同一块存储空间,在带来了方便的同时,也带来了冲突问题,为了保证数据在方法中被访问时的正确性,在访问时加入了锁机制synchronized,当一个线程获得对象的排他锁,独占资源,其他线程必须等待,使用后释放锁即可,

存在的问题:

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

银行取钱不安全例子

package com.ou.p3;//不安全的线程
//两个人去银行取钱,账户public class UnSafeBank {public static void main(String[] args) {Account account = new Account(100,"结婚基金");Drawing boy = new Drawing(account,50,"boy");Drawing girl = new Drawing(account,100,"gril");boy.start();girl.start();}
}class Account{int money;String name;public Account(int money, String name) {this.money = money;//余额this.name = name;//账户名称}
}//银行:模拟取款
class Drawing extends Thread{Account account;//账号名称//取了多少钱int drawingMoney;//手里有多少钱int nowMoney;public Drawing(Account account,int drawingMoney,String name){super(name);this.account = account;this.drawingMoney = drawingMoney;}@Overridepublic void run() {if(account.money - drawingMoney < 0){System.out.println(Thread.currentThread().getName()+"钱不够,取不了");return;}//卡内余额=卡内余额-取走的钱account.money = account.money-drawingMoney;//你手里的钱nowMoney = drawingMoney;System.out.println(account.name+"余额为:"+account.money);System.out.println(this.getName()+"手里的钱"+nowMoney);}
}

同步方法

  • 由于我们可以通过private关键字来保证数据对象只能被非法访问,所以我们只需要针对方法提出一套机制,这套机制就是synchronized关键字,它包括两种用法:synchronized方法和synchronized块
  • synchronized方法控制对"对象"的访问,每个对象对应一把锁,每个synchronized方法都必须获得调用该方法的对象的锁才能执行,否则线程会阻塞,方法一旦执行,就独占该锁,直到该方法返回才释放锁,后面被阻塞的线程才能获得这个锁,继续执行。

同步块

  • 同步块:synchronized(Obj){}
  • Obj称为同步监视器 1.Obj可以是任何对象,但是推荐使用共享资源作为同步监视器。2.同步方法中无需指定同步监视器,以为同步方法的同步监视器就是this,就是这个对象本身,或者是class(反射中讲解)
  • 同步监视器的执行过程
    1. 第一个线程访问,锁定同步监视器,执行其中代码
    2. 第二个线程访问,发现同步监视器被锁定,无法访问
    3. 第一个线程访问完毕,解锁同步监视器
    4. 第二个线程访问,发现同步监视器没有锁,然后锁定并访问
package com.ou.p3;//不安全的线程
//两个人去银行取钱,账户public class UnSafeBank {public static void main(String[] args) {Account account = new Account(1000,"结婚基金");Drawing boy = new Drawing(account,50,"boy");Drawing girl = new Drawing(account,100,"gril");boy.start();girl.start();}
}class Account{int money;String name;public Account(int money, String name) {this.money = money;//余额this.name = name;//账户名称}
}//银行:模拟取款
class Drawing extends Thread{Account account;//账号名称//取了多少钱int drawingMoney;//手里有多少钱int nowMoney;public Drawing(Account account,int drawingMoney,String name){super(name);this.account = account;this.drawingMoney = drawingMoney;}//synchronized 默认锁的是this@Overridepublic  void run() {//锁的对象就是变化的量 需要增删改的对象synchronized (account){if(account.money - drawingMoney < 0){System.out.println(Thread.currentThread().getName()+"钱不够,取不了");return;}//卡内余额=卡内余额-取走的钱account.money = account.money-drawingMoney;//你手里的钱nowMoney = drawingMoney;System.out.println(account.name+"余额为:"+account.money);System.out.println(this.getName()+"手里的钱"+nowMoney);}}
}

JUC线程安全的集合

package com.ou.p3;import java.util.concurrent.CopyOnWriteArrayList;//测试JUC安全类型的集合
public class TestJUC {public static void main(String[] args) throws InterruptedException {CopyOnWriteArrayList copyOnWriteArrayList = new CopyOnWriteArrayList<>();for (int i = 0; i < 10000; i++) {new Thread(()->{copyOnWriteArrayList.add(Thread.currentThread().getName());}).start();}Thread.sleep(3000);System.out.println(copyOnWriteArrayList.size());}
}

相关内容

热门资讯

配置管理的四个要点 配置管理是基础,是关键。做工具平台或系统,一定要重视基础的建设。一定要做...
机构密集调研!长三角区域银行为... 地方性上市银行大获青睐。 5月29日,《国际金融报》记者梳理Wind数据发现,已有超千家机构对24家...
Android文件目录 前言 Android文件目录可以分为内部存储和外部存储,其中外部存储又可以分为私有目录...
用友NC数据库迁移服务解决方案 NC数据库迁移工具操作说明          NC数据库迁移工具的功能:不同数据库之间...
Harbor仓库开启SSL 目录一、部署docker二、安装docker-compose三、安装harbor下载离线安装包&#x...
HTML、CSS学习笔记7(媒... 目录 一、媒体查询 1.max-min-width 2.书写顺序  3.媒体类型 4.媒体查询——l...
Word加载项/插件管理 Word加载项/插件管理前言准备:开启加载项功能区加载项Word加载项COM加载项 前...
Spring产生数据源对象(c... 目录一、c3p01. 添加依赖2. 在resources中创建applicationContext....
ArcScene制作三维地图-... ArcScene制作三维地图-三维模型发布时间:2018-01-17 版权࿱...
【C++】面试101,用两个栈... 目录 1. 用两个栈实现队列  2.包含min函数的栈 3.有效括号序列  4.滑动窗口的最大值 5...
一文说明白,TypeScrip... ● 通过前两章的学习, 我们基本上对于 TS 已经入门了 ● 但是我们会发现, 我们好像对于类型限制...
《JavaEE初阶》计算机网络... 《JavaEE初阶》计算机网络之网络原理(传输层) 前言: 本章主要将介绍传输层的UDP与TCP协议...
菲林格尔筹划控制权变更事项 6... 菲林格尔(603226)筹划易主。 5月30日晚间菲林格尔公告,公司于5月30日收到公司实际控制人丁...
[实战]上传文件的实战问题 [实战]上传文件的实战问题文件上传前的编辑问题上传文件的时机选择=>编辑=>上传 文...
学习笔记:基于SpringBo... 一、发送邮件 发送邮件主要使用JavaMailSender类,使用send方法&#x...
ENet学习笔记 ENet:A deep Neural Network Architecture for Real-T...
Obsidian插件推荐和页面... 1. 插件推荐 custom attachment location 可自定义附件图片的存放位置&#...
7个Python中的隐藏小技巧... Python 是每个程序员都喜欢的语言,因为它易于编码和易于阅读的语法。但是ÿ...
Kotlin实现Service... Service的使用1异步通信方式2Service的启动和停止3希望Activity和Service...
python绘制三维图 一、初始化 假设已经安装了matplotlib工具包。 利用matplotlib.figure.Fi...
每周股票复盘:恺英网络(002... 截至2025年5月30日收盘,恺英网络(002517)报收于15.93元,较上周的15.77元上涨1...
HashTabld底层源码解读 Java源码系列:下方连接 http://t.csdn.cn/Nwzed 文章目录...
常熟银行新注册《常熟农商银行P... 证券之星消息,近日常熟银行(601128)新注册了《常熟农商银行PDF转Word系统V1.0.0.0...
血洗币圈!比特币崩盘,跌至8万... 端午安康,祝大家在牛市中稳健操作,迈向财富自由!别忘了点赞关注,咱们一起把握市场机会! 比特币最近...
k8s部署prometheus k8s部署prometheus 版本说明: k8s:1.24.4 pro...
OpenAI似乎步子迈太大了 ... 出品|虎嗅科技组作者|孙晓晨编辑|苗正卿头图|视觉中国当地时间5月29日,据外媒报道,特拉华州总检察...
代码随想录-58-654.最大... 目录前言题目1.构造二叉树-递归(区间,左闭右开)2. 本...
Git Actions自动发布... Git Actions自动发布部署,非最完善但足够完善和上手的一篇 文章最后附带完整...
【Java (一:12-4 D... DTD&schema 笔记记录一、DTD&schema1. xml约束分类DTD&schema1.1...
#ubuntu# #perf#... 关于 perf相关内容,抓取命令较多,当需要大量数据时每次输入命令会比较...