当前位置: 首页 > wzjs >正文

网页游戏排行榜推选新壹玩seo关键词优化怎么收费

网页游戏排行榜推选新壹玩,seo关键词优化怎么收费,研究院网站建设的内容,网站模块建设建议目录 1.前言 2.正文 2.1悲观锁和乐观锁 2.2重量级锁和轻量级锁 2.3挂起等待锁和自旋锁 2.4互斥锁与读写锁 2.5可重入锁与不可重入锁 2.6公平锁与不公平锁 2.7synchronized优化 2.7.1锁升级 2.7.2锁消除 2.7.3锁粗化 3.小结 1.前言 哈喽大家好,今天来给…


目录

1.前言

2.正文

2.1悲观锁和乐观锁

2.2重量级锁和轻量级锁

2.3挂起等待锁和自旋锁

2.4互斥锁与读写锁

2.5可重入锁与不可重入锁

2.6公平锁与不公平锁

2.7synchronized优化

2.7.1锁升级

2.7.2锁消除

2.7.3锁粗化

 3.小结


1.前言

哈喽大家好,今天来给大家分享Java多线程中常见的锁策略,锁策略不是和Java强相关,但凡涉及到并发编程涉及到锁都会涉及锁策略,概念较多但都很重要,废话不多说让我们开始吧。

2.正文

首先在这里声明一点:以下讲的各种锁,不是针对某一种具体的锁,而是某个具体锁具有“悲观"特性或者“乐观”等特性~~

2.1悲观锁和乐观锁

悲观锁

  • 定义:假设并发冲突一定会发生,因此在操作数据前先加锁,确保同一时刻只有一个线程能访问资源。

  • 特点:强一致性,但性能开销大。

乐观锁

  • 定义:假设并发冲突很少发生,操作数据时不加锁,只在提交修改时检查是否被其他线程修改过。

  • 特点:高性能,但可能需重试。


悲观锁的现实场景

  • 你去银行取钱,柜员会说:"稍等,我先锁上保险箱再给你拿钱。"

  • 为什么?银行默认你会和别人争抢取钱这个操作,必须锁住资源。

乐观锁的现实场景

  • 你和同事改同一份Docs,直接编辑,保存时系统提示:"有冲突,请解决。"

  • 为什么?默认你们不会同时改同一段落,冲突了再处理。

根本区别在于对接下来锁竞争的是否激烈。


对比维度悲观锁乐观锁
默认态度"肯定会有人抢,先锁再说!""应该没人抢,冲突了再说~"
实现方式synchronizedReentrantLock版本号、CAS(如AtomicInteger
性能开销高(上下文切换、阻塞)低(无阻塞,可能重试)
适用场景写多读少(如支付、转账)读多写少(如商品库存、点赞计数)
失败处理线程阻塞等待回滚或自动重试

2.2重量级锁和轻量级锁

重量级锁

  • 定义:依赖操作系统内核的互斥量(Mutex Lock)实现的锁机制,线程竞争时会直接进入阻塞状态,由操作系统负责线程调度。

  • 特点:功能完备(支持公平性、超时等),但性能开销大(涉及用户态到内核态的切换)。

轻量级锁

  • 定义:基于CAS(Compare-And-Swap)自旋实现的锁机制,线程通过循环尝试获取锁,避免直接进入阻塞状态。

  • 特点:性能高(无系统调用),但长时间自旋会浪费CPU资源。


重量级锁的现实场景

  • 你去医院挂号,发现窗口排队的人很多,直接去休息区睡觉(线程阻塞),等护士叫号(操作系统唤醒)。

  • 为什么?因为你知道要等很久,不如让出资源。

轻量级锁的现实场景

  • 你在便利店排队结账,发现前面只有一个人,于是站在原地不停张望(自旋),等对方结束立马抢位置。

  • 为什么?因为等待时间短,不值得去找座位。


  • 重量级锁,当悲观的场景下,此时就要付出更多的代价。(更低效)
  • 轻量级锁,应对乐观的场景,此时付出的代价就会更小。(更高效)

对比维度重量级锁轻量级锁
实现原理通过操作系统内核的互斥量(Mutex)用户态的CAS自旋(如AtomicInteger
线程状态阻塞(挂起)运行中(自旋等待)
性能开销高(上下文切换约1-10μs)低(自旋耗时约0.1-1ns/次)
适用场景高竞争、长临界区低竞争、短临界区
失败处理线程进入等待队列继续自旋或升级为重量级锁

2.3挂起等待锁和自旋锁

挂起等待锁就是重量级锁的典型实现,而自旋锁就是轻量级锁的典型实现。

挂起等待锁(阻塞锁)

  • 定义:当线程获取锁失败时,立即释放CPU资源,进入阻塞状态(挂起),等待被唤醒

  • 核心机制:依赖操作系统调度,涉及线程上下文切换

  • 典型实现:Java的synchronized在重量级锁状态、ReentrantLock.lock()

自旋锁

  • 定义:当线程获取锁失败时,不放弃CPU,而是循环重试(自旋),直到成功获取锁

  • 核心机制:通过CPU空转(忙等待)避免上下文切换

  • 典型实现:Java的AtomicIntegerCAS操作、ReentrantLock.tryLock()自旋版本(以后会详细讲解Java中的CAS)


挂起等待锁场景

  • 你去热门餐厅取号,服务员说:"现在没位,去旁边商场逛2小时再回来"(线程挂起)

  • 为什么合理:等待时间长时,干等着(自旋)反而浪费精力

自旋锁场景

  • 你在便利店排队,收银员说:"稍等1分钟马上好",你选择站着玩手机等待(自旋)

  • 为什么合理:短暂等待时,来回走动(上下文切换)更耗能


对比维度挂起等待锁自旋锁
等待机制立即释放CPU进入阻塞状态保持CPU占用循环检测
系统开销高(上下文切换约1-10μs)低(但浪费CPU周期)
实现复杂度高(需OS支持线程调度)低(CAS即可实现)
适用场景锁持有时间长(>1ms)锁持有时间短(<1μs)
线程状态BLOCKED/WATINGRUNNABLE
公平性通常可实现公平通常是非公平的
典型应用数据库事务、文件IO计数器、状态标志

2.4互斥锁与读写锁

分析下这个读写锁:多个线程读取一个数据,是本身就线程安全的。多个线程读取,一个线程修改,肯定会涉及到线程安全问题。如果你把读和写都加上普通的互斥锁,意味着锁冲突将会非常严重,读锁和读锁之间不互斥,读锁和写锁互斥,写锁和写锁之间也互斥。于是乎读写所的存在,保证线程安全的前提下,降低锁冲突概率提高效率。


互斥锁(Mutex Lock)

  • 定义:独占锁,同一时刻只允许一个线程访问共享资源

  • 特点:强排他性,读/写操作同等对待

  • 典型实现:Java的synchronizedReentrantLock

读写锁(ReadWrite Lock)

  • 定义:分离锁,将读操作和写操作区别对待

  • 特点:允许多个读线程并发,写线程独占

  • 典型实现:Java的ReentrantReadWriteLock


互斥锁场景

  • 图书馆自习室规则:"每次只允许一人进入,无论你是看书(读)还是做笔记(写)"

  • 结果:即使多人只想看书,也得排队轮流进

读写锁场景

  • 改进后的规则:"看书的人可以一起进,但做笔记的人必须单独使用房间"

  • 结果:读书效率提升,写作时仍保证独占


对比维度互斥锁读写锁
并发粒度完全互斥读读并发,读写/写写互斥
吞吐量低(所有操作串行)高(读操作可并行)
实现复杂度简单复杂(需维护读/写状态)
适用场景读写操作耗时相近读多写少(≥5:1)
线程饥饿风险写线程可能被读线程长期阻塞
锁升级不支持读锁不能升级为写锁(会死锁)
公平性可公平/非公平可公平/非公平

2.5可重入锁与不可重入锁

之前文章中讲解过这里不过多展开了喔~简单总结~


可重入锁(Reentrant Lock)

  • 定义:同一个线程可以多次获取同一把锁,锁会维护一个持有计数(hold count)

  • 关键特性:防止线程自己造成死锁

  • 典型实现:Java的synchronizedReentrantLock

不可重入锁(Non-reentrant Lock)

  • 定义:线程获取锁后,再次尝试获取会立即阻塞/失败

  • 关键特性:严格线性获取锁

  • 典型实现:早期的简单锁实现、某些特定场景的自旋锁


可重入锁场景

  • 你家大门装了智能锁,你(线程)进入时:

  1. 第一次进门:验证指纹(获取锁)
  2. 进卧室时:不再验证(重入计数+1)
  3. 离开卧室:不真正锁门(计数-1)
  4. 最终出门:才真正上锁(计数归零)

不可重入锁场景

  • 老式钥匙锁的尴尬情况:

  1. 你进门后锁上门(获取锁)
  2. 想进里屋时发现需要钥匙(再次获取锁)
  3. 钥匙插在外门锁上(死锁形成)
  4. 最终困在门厅里(线程阻塞)

对比维度可重入锁不可重入锁
死锁预防避免同一线程自我死锁可能因递归调用导致自我死锁
实现复杂度高(需维护线程ID和计数)低(只需布尔状态)
性能开销略高(计数器操作)略低
适用场景递归调用、回调函数简单线性流程
锁释放必须完全释放(计数归零)单次解锁即释放
典型应用Java同步机制、数据库事务某些内核锁、特殊优化场景

2.6公平锁与不公平锁

公平锁(Fair Lock)

  • 定义:按照线程请求锁的先后顺序分配锁,遵循FIFO(先进先出)原则

  • 特点:避免线程饥饿,保证公平性

  • 实现方式:通过队列维护等待线程(如ReentrantLock(true)

非公平锁(Non-fair Lock)

  • 定义:允许线程插队获取锁,不保证请求顺序

  • 特点:吞吐量高,但可能导致线程饥饿

  • 实现方式:直接尝试CAS获取锁(如synchronizedReentrantLock()默认模式)


公平锁场景

  • 银行VIP窗口叫号系统:"请A001号到3号窗口"(严格按取号顺序服务)

  • 优点:先来的人一定能先办业务

  • 缺点:即使窗口空闲,也必须叫号

非公平锁场景

  • 地铁早高峰排队:"车门一开,所有人挤着上车"(谁快谁上)

  • 优点:车厢利用率高(减少空置时间)

  • 缺点:可能有人永远挤不上去


对比维度公平锁非公平锁
排队机制严格FIFO允许插队(新线程可直接竞争)
吞吐量较低(约降低30%)较高
线程饥饿不会发生可能发生
实现复杂度高(需维护等待队列)低(直接CAS)
响应时间稳定但较长不稳定(可能极快或极慢)
适用场景交易系统、计费系统高并发缓存、计数器
JVM实现ReentrantLock(true)synchronizedReentrantLock()

公平锁:

public class FairLockDemo {private static final ReentrantLock lock = new ReentrantLock(true); // 公平模式public static void main(String[] args) {for (int i = 0; i < 3; i++) {new Thread(() -> {lock.lock();try {System.out.println(Thread.currentThread().getName() + "获取锁");} finally {lock.unlock();}}, "Thread-" + i).start();}}
}
// 输出保证按线程启动顺序获取锁

非公平锁:

public class NonFairDemo {private static final ReentrantLock lock = new ReentrantLock(); // 默认非公平public static void main(String[] args) {// 先让主线程持有锁lock.lock();new Thread(() -> {System.out.println("子线程尝试获取锁");lock.lock();  // 这里会插队!System.out.println("子线程获取成功");lock.unlock();}).start();Thread.sleep(100); // 确保子线程启动System.out.println("主线程释放锁");lock.unlock();  // 释放后子线程可能抢到,即使有其他等待线程}
}

2.7synchronized优化

2.7.1锁升级

JVM根据竞争情况,动态调整synchronized的锁状态,从低开销到高开销逐步升级,避免一刀切使用重量级锁。 JVM没有提供锁降级。

graph LRA[无锁] -->|首次获取| B[偏向锁]B -->|有竞争| C[轻量级锁]C -->|竞争加剧| D[重量级锁]
  1. 偏向锁(Biased Locking)

    • 场景:单线程反复访问同步块

    • 原理:在对象头记录线程ID(无需CAS)

  2. 轻量级锁(Thin Lock)

    • 场景:多线程交替执行(无真正竞争)

    • 原理

      • 栈帧中创建Lock Record

      • 通过CAS将对象头指向Lock Record

  3. 重量级锁(Heavyweight Lock)

    • 场景:高并发竞争

    • 原理:通过ObjectMonitor实现

    • 开销:上下文切换约1-10μs


补充以下何为偏向锁:
刚一上来,不是真加锁, 而是只是简单做一个标记,进行synchronized。这个标记,非常轻量, 相比于加锁解锁来说,效率高很多~如果没有其他线程来竞争这个锁,最终当前线程执行到解锁代码,也就只是简单清除上标记即可~~(不涉及真加锁,真解锁)如果有其他线程来竞争,就抢先一步,在另一个线程拿到锁之前,抢先拿到锁真假锁了,偏向锁 =>轻量级锁,其他线程只能阻塞等待。

2.7.2锁消除

这也是编译器优化的一种体现。


概念:编译器会判定,当前这个代码逻辑是否真的需要加锁,如果确实不需要加锁,但是你写了 synchronized,,就会自动把synchronized给去掉,像一些判定不清楚的情况,不会触发锁消除。

如果到处有synchronized,意味着优化机制,只能把其中一部分,他能明确判定的给优化掉,还会有很多不应该使用, 但是编译器也优化不调。

2.7.3锁粗化

概念
将相邻的多个细粒度锁合并为单个大锁,减少锁申请/释放开销。(加锁和解锁之间,包含的代码越多,就认为锁的粒度就越粗)

触发场景

// 原始代码
for (int i = 0; i < 100; i++) {synchronized(obj) { // 每次循环都加锁doSomething();}
}// 优化后等效代码
synchronized(obj) { // 合并为单个锁for (int i = 0; i < 100; i++) {doSomething();}
}

以上三种做个总结:

优化手段适用场景性能提升幅度实现层级
锁升级所有synchronized场景10-100倍JVM运行时
锁消除线程私有对象2-5倍JIT编译期
锁粗化密集短锁操作1.5-3倍字节码优化阶段

 3.小结

今天的分享到这里就结束了,喜欢的小伙伴点点赞点点关注,你的支持就是对我最大的鼓励,大家加油!

http://www.dtcms.com/wzjs/214803.html

相关文章:

  • 龙岗 网站建设郑州seo网络推广
  • 数据库修改网站后台密码成都网站建设团队
  • 太原网站如何制作做一个app软件大概要多少钱
  • 南通网站备案以下属于网站seo的内容是
  • 二级建造师证书查询官网怎么样关键词优化
  • 怎样在华为云服务器里建设网站郑州seo线下培训
  • 苏州网站开发公司招聘信息品牌运营具体做什么
  • 宝鸡企业网站建设关键词排名推广方法
  • 现在一些产品网站开发用的啥框架游戏挂机赚钱一小时20
  • 国内ui网站企业网站制作教程
  • 网站建设的基本内容石家庄最新新闻事件
  • 体育网站建设二十四个关键词
  • 建设网站如何进行网站备案优化网站的公司哪家好
  • 单页营销型网站模板下载app001推广平台官网
  • 网站如何做成app哪里有竞价推广托管
  • 市场营销目标怎么写推动防控措施持续优化
  • 自助建站免费建站五个平台网推项目
  • wordpress支持的视频格式seo优化师是什么
  • 阳江网站建设2023年免费b站推广大全
  • 网红营销对消费者的影响seo概念的理解
  • 宜宾商城网站建设dz论坛seo
  • 哈尔滨软件开发公司排名排名优化软件点击
  • 网站seo操作百度网页推广怎么做
  • 威海德嬴网站建设企业网站定制
  • 建个网站谷歌seo外链
  • 佛山网站哪家最专业淘宝代运营公司
  • 县政府网站建设实施方案如何创建微信小程序
  • 网站地图代码seo技术助理
  • 互联网排名前100的公司宁波seo关键词培训
  • 知名网站域名如何建立自己的网站