V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GraySoul
V2EX  ›  程序员

小白真诚求问, Java web 开发究竟啥场景需要用到多线程各种天花烂醉锁?

  •  2
     
  •   GraySoul · 205 天前 · 10720 次点击
    这是一个创建于 205 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本人是个啥都会点的多栈开发。 最近在准备面试,看到 java 面试题里考各种并发各种锁,一脸懵逼。 我写了这么多年 web 就没用过多线程,感觉自己属实弱,我单纯地觉得,真有那么多耗时需求扔消息队列里不就行了么?现在 java web 到底都在开发啥玩意,为啥这些都是面试重点呢?

    没别的意思,是真不懂。。想问问具体有哪些场景。别的语言的程序员朋友们也欢迎指教,我写其他语言的 web 也没用过。。。我可能就是传说中的 crud 工程师= =

    107 条回复    2023-03-11 09:59:21 +08:00
    1  2  
    xhldtc
        1
    xhldtc  
       205 天前   ❤️ 2
    面试造火箭呗,你可以没用过,但是你得懂。面试的时候两个人都没有用过,你懂他不懂,你说招哪个人?大环境太卷没办法
    zjsxwc
        2
    zjsxwc  
       205 天前
    爬虫,用线程开 n 个连接“攻击”同一个服务器接口。2333
    FawkesV
        3
    FawkesV  
       205 天前   ❤️ 2
    我们这边有这样子的场景:可能存在大批量数据查询的时候,按数据量拆分多线程查询。
    例如有一个接口需要查询指定的 ID 数据信息,需要查询到数据中台。可能最多存在 1000 个 ID 。就拆分每次查询 20 个,使用线程池查询,再将数据组装在一起。
    li746224
        4
    li746224  
       205 天前   ❤️ 1
    api 服务算 java web 吗?如果算的话,我开发过的里面好像就通知服务和生成报表的服务用到了多线程。
    xiangyuecn
        5
    xiangyuecn  
       205 天前   ❤️ 3
    ???
    ???

    http 请求本身就是多线程,不是啥都会点,你这是啥也不会
    crysislinux
        6
    crysislinux  
       205 天前 via Android   ❤️ 1
    web 开发感觉 Java 进程层面的锁不太用的上,除非你设计的就是单机程序,否则就是用分布式锁或者数据库层面的锁了。
    tool2d
        7
    tool2d  
       205 天前   ❤️ 1
    "我写了这么多年 web 就没用过多线程",前端的 web worker 就是多线程啊,而且不用上锁,都是用 json 消息在线程之间传输数据的。

    别说 java ,任何语言锁多了后,维护都很复杂。
    roundgis
        8
    roundgis  
       205 天前 via Android
    只是抽插數據庫那基本上用不上
    tool2d
        9
    tool2d  
       205 天前   ❤️ 3
    @xiangyuecn "http 请求本身就是多线程,不是啥都会点,你这是啥也不会'

    http 请求可以不开线程的,网络请求本来就是非阻塞 IO ,不会阻挡后面代码正常执行。比如 nodejs 就是单线程。
    GraySoul
        10
    GraySoul  
    OP
       205 天前   ❤️ 1
    @crysislinux @tool2d 我说的没用过多线程是指:在 web 场景直接使用各种锁来对共享数据做并发处理。

    原理上的多线程我懂,以及在数据库层面 web 框架层面的多线程应用我也大体都了解,我显然不是指这些底层场景。。

    @xiangyuecn 没错我啥都不会,感谢批评
    pierswu
        11
    pierswu  
       205 天前
    这是在考察逻辑能力
    GraySoul
        12
    GraySoul  
    OP
       205 天前
    @FawkesV 非常感谢提供具体场景,不过类似这样的场景我感觉就是不太涉及共享数据的冲突,完全就是开完线程之后把各自的结果一归拢,确实用不上面试上那些玩意。
    rqxiao
        13
    rqxiao  
       205 天前   ❤️ 1
    多线程:线程池处理大批量需要 io 的任务 ;分布式锁:mq 消费幂等性,下单减库存的线程安全
    GraySoul
        14
    GraySoul  
    OP
       205 天前
    @roundgis 好一个抽插,这是能播的么
    libook
        15
    libook  
       205 天前   ❤️ 1
    面试是测试你水平上限的,所以肯定要问一些面试官认为代表水平上限的问题,只问 CRUD 谁都会,一百份简历只要 5 个人怎么办。

    知己知彼百战不殆,你只有摸清楚了面试官的思路,才能更好拿捏面试。
    ljrdxs
        16
    ljrdxs  
       205 天前
    “真有那么多耗时需求扔消息队列里不就行了么?”

    公司里应该真是这样的。
    1 楼正解。面试造火箭。
    GraySoul
        17
    GraySoul  
    OP
       205 天前
    @tool2d @xiangyuecn 可能指的是 web 容器针对每个请求都会建一个线程来处理。他要是说的是发起 http 请求,那到底谁不懂还真是个问题。。
    hhjswf
        18
    hhjswf  
       205 天前   ❤️ 1
    消息队列不用买啊?你说用开源自建,那也要部署一套占用资源。能用 Java 解决你不用,再引入一个中间件依赖,这很好吗?
    xinhochen
        19
    xinhochen  
       205 天前   ❤️ 1
    说一个场景:用户在页面订阅由 websocket 推送的数据,关闭页面后需要移除订阅关系。当用户打开多个页面或者不同客户端使用,对于这个订阅关系的维护就用到了锁。当然,这个锁可能是提前实现好的组件内部使用的,开发者可以不用关心。
    bugmakerxs
        20
    bugmakerxs  
       205 天前   ❤️ 1
    1. 避免程序启动时环境初始化方法被调用多次
    2. 请求方超发导致消费者并发消费同一条消息
    3. 多并行任务全部结束后执行另一个任务

    用到的地方确实不多,不过确实有点用
    vaaagle
        21
    vaaagle  
       205 天前
    比如,客户让你,将所有的项目一键打包成 excel 然后在生成压缩包最后还得附上一个这些项目的 excel 清单的时候
    ps:上面的人不懂拒绝掉,最后分到你手上
    buffzty
        22
    buffzty  
       205 天前
    并发时会用到.
    1. 能不用锁就不用锁
    2. 锁的越少越好
    3. 小心死锁
    byte10
        23
    byte10  
       205 天前   ❤️ 1
    真有那么多耗时需求扔消息队列里不就行了么? 那你怎么去消费这些队列呢,你肯定也是用多线程去消费吧。当然一些 mq 可以直接配置多线程的数量。

    多线程还是挺讲究的,最小核心数和最大的核心数,还有任务队列 queue 的数量限制,拒绝策略,都是有讲究的,不同场景下是不一样的设置。大多数业务可能触碰不到这部分,只是很多框架都集成这些多线程的设计。
    dqzcwxb
        24
    dqzcwxb  
       205 天前
    现在有一个需求,你要请求 5 个第三方接口进行数据汇总,接口耗时分别为 1s 2s 3s 4s 5s 且无法从第三方获得优化
    常规阻塞执行需要 15s 多线程并行执行可以压缩到 5s
    把接口换成数据库换成其他服务调用,就是多线程的应用场景
    而锁就更简单了,需要保证强一致性 但是为了性能一般只追求最终一致性
    CAP:一致性( Consistency )、可用性( Availability )、分区容错性( Partition tolerance )保证 A 和 P 的情况下牺牲 C
    MoYi123
        25
    MoYi123  
       205 天前   ❤️ 2
    web 开发里会下面这个就足够了

    lock.acquire()
    do sth
    lock.release()

    会用到什么 2-3 个锁套来套去, cas 之类, 先看看是不是自己的设计有问题.
    statumer
        26
    statumer  
       205 天前
    @dqzcwxb #24 你说的这个场景是最基础的 map reduce ,调 api 就能实现。
    ajaxgoldfish
        27
    ajaxgoldfish  
       205 天前 via Android
    写 demo 的时候用过一次,多个线程压测拿到结果静态变量+1 ,就用过一次
    GraySoul
        28
    GraySoul  
    OP
       205 天前 via Android
    感谢各位的回复,看完之后我稍微没那么焦虑了。我看面试题后,是真的以为其他程序员写个 web 业务都各种上天花乱坠锁的,就我们业务简单个一比连个多线程都用不到。

    最常规的锁,最基本的多线程应用我是熟悉的,啥语言都写过,golang 的 goroutine 啥的也都搞过。对操作系统的进程、线程以及语言级别协程啥的都有基本认知。我问这个问题是真的自己在 web 业务里没用过。

    看了大家的回复,我觉得普通的 web 业务应该是用不了太多,但自己写框架或者底层库什么的应该会常用。学了就是自己的,不怕多学,只是对于我面个普通 web 开发要做这些面试题有点点困惑。既然是卷的问题,那也没啥好多说的,高考也是这么过来的的,学起来就是。
    rapperx2
        29
    rapperx2  
       205 天前
    我写代码经常就会碰到,跟业务场景有很大关系
    GraySoul
        30
    GraySoul  
    OP
       205 天前 via Android
    @MoYi123 这个确实简单,但我还是没想到啥场景会用。web 开发中常见共享资源就是数据库、中间件这些。他们有各自的锁机制。java 这边共享资源能是啥呢?我难道要在内存里搞个共享的 map ,让不同的请求修改?这怎么想怎么二。。。
    GraySoul
        31
    GraySoul  
    OP
       205 天前 via Android
    @rapperx2 卧槽 求指教 能否举个例子🙇 就像我在 30 楼说的,写 web 业务,共享资源都是数据库、中间件什么的,各有各的锁机制。但 java 这个层面需要锁做啥真的没用过
    cloudzhou
        32
    cloudzhou  
       205 天前
    如果写中间件,那么多线程就是基本知识了
    而一个好的框架,就是让开发者不需要过度考虑并发问题
    sbex
        33
    sbex  
       205 天前   ❤️ 1
    以前觉得没啥,但认识了几个 sb 之后发现对于多线程与锁的机制了解这种东西,你可以不知道有多细,但是必须知道有这个东西。

    说多了都是泪,跟 sb 相处的日子。
    14104chk
        34
    14104chk  
       205 天前   ❤️ 1
    想优化,多线程会用得很多
    中间件、数据库的锁只能管自身的事情,但如果中间件、数据库的操作要合并在一个事务里,就需要自己去做。JAVA 的锁可以保证单个进程里面的事务隔离性
    dqzcwxb
        35
    dqzcwxb  
       205 天前
    @statumer #26 op 问的不就是基础?什么代码不是调 api?
    YepTen
        36
    YepTen  
       205 天前   ❤️ 1
    和业务场景深度绑定。
    1. 批量下载文件,比如传个 List 参数。一个线程 for 循环那多慢啊。
    2. 批量入库,给你一批数据,不能 batchinsert 的时候,for 循环明显不行啊,多线程走起。
    3. 一些后台线程等
    cloudzhou
        37
    cloudzhou  
       205 天前   ❤️ 1
    @GraySoul 给你一个我最近遇到现实例子:
    一个很复杂的工作 job ,对一个对象进行操作,比如同时进行 a 、b 、c 、d 处理
    同时之间这些处理逻辑,可能存在依赖关系,比如 a 完全可以独立运行,c 依赖 b 、d 完成之后才运行,等等

    要求:
    1. 尽量多并发执行,同时避免线程空等待
    2. 严格按照依赖关系运行,并发安全
    3. 最后有个等待动作,要求所有操作完成,job.wait

    如果更高要求:
    1. 是否可以中途中断,取消当前 /后续执行
    2. 某个操作异常处理如何,是否做到 继续 or 中断
    3. 每个处理逻辑,是否可以影响调度过程,比如跳到指定逻辑,或者跳过指定逻辑
    4. 有没有最大等待时间
    5. 是否可指定等待某个阶段完成就好了,不需要所有都明确完成
    6. 防止滥用资源,是否可以控制最大并发数

    想想,你要怎么设计
    GraySoul
        38
    GraySoul  
    OP
       205 天前
    @14104chk 愿意付费咨询,求一个真实场景学习,请你一顿午饭 哈哈哈
    cloudzhou
        39
    cloudzhou  
       205 天前
    @GraySoul 我这个就真的是真实场景
    adoal
        40
    adoal  
       205 天前
    用面试排除掉你,录用比你牛叉很多倍的人,但他们干的是你也能干的活,因为从业的人太多了。
    TtTtTtT
        41
    TtTtTtT  
       205 天前   ❤️ 1
    发生问题:并行处理多个 IO 任务,减少总等待时间
    解决方案:加入消息队列
    然后,产生了一大堆新的问题:消息队列的高可用和一致性,超时和 session 管理。

    就,明明是杀鸡,用 Java 能解决的事情,为啥要用牛刀呢。。
    GraySoul
        42
    GraySoul  
    OP
       205 天前
    @cloudzhou 费心了,非常感谢,我工作中确实没遇到过这种场景。我有个问题是这个共享的对象具体是什么呢,是内存里的对象?从数据库里取回来的一个大的数据对象?由于很大,所以需要各种线程并发取操作?
    hervey0424
        43
    hervey0424  
       205 天前
    @zjsxwc 我感觉平时写的程序和爬虫差不多, 多个线程攻击数据库
    cloudzhou
        44
    cloudzhou  
       205 天前
    @GraySoul 不是这个对象大,是这个对象上面要填充的数据大,可能触发多个 rpc ,db 等
    Biluesgakki
        45
    Biluesgakki  
       205 天前   ❤️ 4
    @roundgis 第一次见用“抽插”这个词来形容操作数据库的
    apples01
        46
    apples01  
       205 天前
    @xiangyuecn 他意思是他自己写过的业务逻辑没有遇到过多线程
    yazinnnn
        47
    yazinnnn  
       205 天前
    我觉得不会也没关系, 你能找到另外一条赛道来跑赢你的竞争对手就行, 比如用 stm 和结构化并发来处理并发编程
    levintrueno
        48
    levintrueno  
       205 天前
    @cloudzhou 感觉,CompletableFuture 蛮符合的
    GraySoul
        49
    GraySoul  
    OP
       205 天前
    @cloudzhou 噢噢,我大概明白了,这个场景是不是就是假设我有那么一个对象要返回给前端,但是这个对象里面的数据需要从多个数据源那里去获取,而且不同数据源获取到的数据之间有依赖关系,可能先从 A 数据源获取完了个 x ,传给 B 数据源才能获取 y ,等等。这个场景不考虑你说的更高要求,我个人感觉用不着啥锁,因为共享对象里面可以设置多个 key ,获取到不同数据往不同 key 里塞就好了,会涉及到冲突么?但这确实是多线程实践的一个好例子。再次感谢!这里面关于是否涉及对锁的应用,还望不吝赐教!
    shakeyo
        50
    shakeyo  
       205 天前
    当前碰到一个网盘场景,刚好发出来看看大佬们的想法
    数据库中基于路径枚举以及邻近表的方式存储了一个文件目录结构
    当多个用户对某个文件夹以及子文件夹进行操作的时候,可能会导致冲突
    例如,用户 a 在 /1/2 文件夹下上传或者移入文件、文件夹
    用户 b 同时对 /1 移动或者 rename ,或者删除,此时很显然造成了冲突,如果不做任何处理,用户 a 将碰到部分文件上传失败
    简单的思路就是根据路径设计一套读写锁,如果写目录,则把当前文件往上全部加锁,其他操作发现有写锁要么等待,要么友好提示用户稍后再试
    hzzh
        51
    hzzh  
       205 天前
    请教各位大佬,现在到底什么语言不卷,我三年前从 Java 转到 C#,下次换工作本来想提前准备下再找个 Java ,看诸位说的这么卷,那到底提前准备个啥方向会好点
    GraySoul
        52
    GraySoul  
    OP
       205 天前
    @yazinnnn 学习了,听都没听过= = 其实我的赛道是接项目赚点小钱,感觉那些高大上的都和我不沾边。。。毕竟连并发都没咋写过,基本都靠框架和库就解决了,不知道以后这职业生涯要咋混下去了;)
    diagnostics
        53
    diagnostics  
       205 天前   ❤️ 2
    丢消息队列你也要保证安全发布啊。。。

    生产者-消费者是异步了,你考虑过异步转同步的场景没? Thread Leak 考虑过没?

    公司业务大了,需求多了,各种问题就有了。

    假设你上异步编程,Reactive Programing ,里面的 Operator 如何工作,怎么用的线程清楚了吗?

    面试就是筛选你的能力,你的学习能力不能在面试中考核出来,如果可以那么你不会也没关系,因为你学的快。

    还搞不清楚,Golang 里面写 Raft 也用到了各种锁,这不是 Java 的问题
    cloudzhou
        54
    cloudzhou  
       205 天前
    @levintrueno 肯定用 Future ,但是你按照我上面要求写一个,就发现很多小细节,能体现并发掌握如何
    cloudzhou
        55
    cloudzhou  
       205 天前
    @GraySoul 依赖关系你怎么处理,等待怎么等待
    yazinnnn
        56
    yazinnnn  
       205 天前   ❤️ 1
    @GraySoul
    并不是高大上, 无锁并发同样属于面试造火箭 工作拧螺丝的范畴, 基本上工作中会
    lock.lock
    try{

    }finally{
    lock.release
    }

    或者
    lock.withLock{
    }

    就够了

    stm 是面试唬人的, 工作中不可能让你真写
    haython
        57
    haython  
       205 天前
    你肯定是写 php 的
    yangzhezjgs
        58
    yangzhezjgs  
       205 天前   ❤️ 2
    后端并发一般用在中间件里,典型的几个场景:
    1.大量客户端同时发送请求,所谓的高并发,这里需要考虑如何处理大量的网络连接,以及处理协议,调用业务逻辑等,需要用到多线程。
    2.有状态的应用,典型的是数据库,缓存之类的涉及存储的组件,需要考虑多个用户同时写入发生错误,一般就会用涉及事务,会用到到锁或者 MVCC 之类的技术。
    3.也是类似上面的场景,如数据库之类的,会设置定时任务定期让后台线程进行资源回收,备份之类的操作也会涉及多线程。
    一般的业务场景中,需要多线程的场景都被框架或者组件内部封装好了,学习的主要目的是使用中间件的时候,理解为什么要这么设计,大多数需要真的写多线程,一般找不到现成的框架,需要真的自己写的时候,但是这种情况太少了
    wupher
        59
    wupher  
       205 天前
    我自己在工作代码中实际碰到的:

    - 多任务调度,一般会结合线程组任务管理和楼主说的锁。(有些任务不允许并行,只能依次或者限量执行)

    - 多服务调用,用户 web call ,业务要调 A,B,C,D,E 然后根据不同的返回结果返回相异。顺序调用会超时且用户体验不好,需要异步并发调用。

    BTW: 这两种一般碰多了都会组中间件。
    tulongtou
        60
    tulongtou  
       205 天前
    @tool2d 用 python ,就一把锁,完全不用考虑(狗头
    zero47
        61
    zero47  
       205 天前
    @TtTtTtT
    @cloudzhou
    @shakeyo
    没看到你们回复之前,我都怀疑骂面试已经是政治正确了。
    14104chk
        62
    14104chk  
       205 天前   ❤️ 1
    @GraySoul readis 缓存数据就是最好的场景。

    A 、a1 查缓存没有数据,a2 去查数据库,a3 数据缓存到 redis ,a4 返回数据
    B 、b1 数据库更新,b2 删掉缓存。

    逻辑简单,想写好不轻松。
    这里面最容易掉进去的陷阱是执行顺序这样 a1,a2,b1,b2,a3,a4
    写完之后,你可以写一个验证程序,对 a1,a2,a3,a4,b1,b2 做排列组合,看最终结果和预期的对不对
    rapperx2
        63
    rapperx2  
       205 天前
    @shakeyo 坐等 大佬给思路
    14104chk
        64
    14104chk  
       205 天前
    @cloudzhou 这主要是任务的调度,可以把任务做成多棵树。树 1:a ,树 2:c ->(b 、d)。 开始运行,或者每一个任务运行完之后,把所有树里面没有子节点,或者子节点全部运行结束的任务扔到线程池
    zzzzz001
        65
    zzzzz001  
       205 天前
    多线程你无时无刻都在用,只不过封装在框架里面
    RainCats
        66
    RainCats  
       205 天前   ❤️ 1
    最近用过多线程的场景:
    1 )异步去调用消息服务发一些不重要的通知(短信、邮件),因为付费版 MQ 开 topic 要钱的
    2 )导出 Excel 的时候如果数据量达到一定数量级,走多线程去渲染不同的 sheet
    3 )导入数据的时候也可以通过多线程来加速一下
    4 )某接口有一堆远程调用的时候可以通过多线程来加速一下,串行请求太慢了
    Promtheus
        67
    Promtheus  
       205 天前   ❤️ 1
    应用场景其实就是在面试的时候,不过讲真,就算平时用不到也需要知道。因为不知道的东西是肯定不会用的。只有先学到了才会知道是不是要用。
    GraySoul
        68
    GraySoul  
    OP
       205 天前 via Android
    @haython 确实写过 php ,但感觉这和业务场景和规模关系比较大,我 nodejs ,java 的后台业务也都写过,但真就没遇到啊。。。
    b123405060
        69
    b123405060  
       205 天前   ❤️ 1
    多线程示例 1. 数据入库的时候, 多个线程同时入库。2. 查询数据的时候, 多个线程同时查询, 最后进行汇总。 锁: 多个用户同时抢单的时候, 你不加锁, 那不是都抢到了! 在做删除任务的时候, 你不加锁, 双击删除的时候, 会删除两次(也算是解决幂等问题)。
    14104chk
        70
    14104chk  
       205 天前
    @shakeyo 简单点就是加锁 lock(/1)->lock(/2)->unlock(/2)->unlock(/1)
    有一个优化点,不过要看你的业务允不允许。
    删除、重命名、移动,这些都是改的文件的组织结构,不是文件本身。文件本身只有修改。
    可以把所有文件都存在一个目录下,然后把目录结构存数据库,表结构类似(id,pid,name,deleted,file_path)。file_path 是真实的物理路径。id 、file_path 永远不变。
    其它的 删除、重命名、移动 只需要在数据库里面改 pid,name,deleted
    只有修改文件本身的时候,才需要加锁
    修改 /1/2 的时候,允不允许删除 /1 ,这需要业务去确定,但不管允不允许,都不可以不用等待修改 /1/2 的锁
    不过修改 /1/2 完的时候,用户可能发现目录已经改变或删除了,这需要在业务上给用户反馈
    devswork
        71
    devswork  
       205 天前   ❤️ 2
    多线程的话,爬虫,现抓取到 URL list ,然后开启线程池,批量爬取+解析 DOM+存入数据库,如果一个一个跑,太慢了,多线程直接起飞。
    锁,我们用到 redis 锁,比如某个 API ,一个用户在指定秒数内只能访问 1 次,那就用到 url+用户 id (或 token )组合 key 的锁,调用接口前判断锁,进而防止重复请求。
    cloudzhou
        72
    cloudzhou  
       205 天前   ❤️ 1
    @14104chk 能提到树,我觉得算 ok 一半了,就是实际实现,还是很考验的,我这个例子就是说明并发的存在和挑战
    shakeyo
        73
    shakeyo  
       205 天前
    @14104chk 现在就是你说的这个方案,数据库只有文件目录结构的索引,路径枚举的方式存储
    真实文件是存储到 oss 上的,这里讨论要用到锁的场景指的也是针对文件目录树的冲突
    那你的思路跟我是一样的,操作子目录得一直向上锁定
    再蹲一个更好的思路
    shakeyo
        74
    shakeyo  
       205 天前
    @cloudzhou 你这个应该是要基于 dag 实现一个任务调度器
    GraySoul
        75
    GraySoul  
    OP
       205 天前 via Android
    @14104chk a1,a2,b1,b2,a3,a4 这个过程的问题是 a4 返回的数据是过期的不是 b1 最新改的吧。好吧,这种严苛的实时性我们确实不需要呢。。。但这个怎么用 java 锁来解决呢?你把 A 的代码用锁给锁了保证了原子性,但 B 该怎么执行还是怎么执行。

    所以这是不是需要用到分布式锁呢?这其实有点偏中间件了,中间件需要搞这些锁技术我很理解,但 java 写个 api 的业务场景我还是觉得用不到啥锁。。🙇
    fkdog
        76
    fkdog  
       205 天前
    一个任务集群节点,要保证一个时间点只有一台机器执行某个任务,那么加锁是最简单的处理方法。
    你用队列的话,一个任务你得重复执行 N 次。还要做额外的去重操作。
    tairan2006
        77
    tairan2006  
       205 天前
    你写个连接池也要用锁啊。。
    NoString
        78
    NoString  
       205 天前   ❤️ 3
    作为练习时长四年半一线 CRUD 程序员 在以下场景使用锁或者多线程解决问题更丝滑简单,更多是在解决分布式系统中的 CAP 原则带来的问题
    1.广告投放做预算
    2.商城商品卖库存
    3.多机器刷 Token
    4.聚合 API
    5.拉取报表数据
    6.多请求合并
    7.电商积分、优惠券消耗

    上面的场景通过队列也能解决,但有些场景我们对一致性的要求并不是最终一致,队列带来的消息可靠问题和时延以及剥离事务并不一定适用,因地制宜很关键

    面试中的锁脱离场景 比如让你讲讲 AQS 、讲讲 synchronized 、自旋锁、乐观、悲观锁就是八股性质更多,但掌握这些东西能更好的让你理解 mysql 的锁设计、java 的锁设计、以及线程池的底层设计。
    546L5LiK6ZOt
        79
    546L5LiK6ZOt  
       205 天前   ❤️ 1
    看到很多人说并行处理 io 需要用多线程,其实 nio 出来很多年了,一个线程就能同时管理多个 fd ,大多数 io 相关的类库都会提供异步接口,例如 redis client ,kafka client ,apache http client ,dubbo ,es client 等都有异步接口,比开多线程同步调用性能会好点(用多线程还得评估线程数,麻烦)。也有些例外,例如 jdbc ,只有同步接口,所以并发操作数据库只能开多线程了。
    GraySoul
        80
    GraySoul  
    OP
       205 天前
    好了 感谢大家 我意识到自己错了,我现在就去学各种天花乱坠锁,研究到最后我再去读读底层源码,我要卷的让面试官爹都不认识。他日我若面试成功,回来回馈家人们。
    GraySoul
        81
    GraySoul  
    OP
       205 天前
    @tairan2006 (大哭)连接池难道不是直接配置上就完事了么= =HikariCP 什么的,你意思我自己实现一个连接池? 我一个 crud 工程师就这么被你们逼上了开发中间件的悬崖上。。。
    GraySoul
        82
    GraySoul  
    OP
       205 天前
    @546L5LiK6ZOt 我确实喜欢 vert.x 和 nodejs 的那种 feel ,就审美很一致= =
    GraySoul
        83
    GraySoul  
    OP
       205 天前
    @NoString “上面的场景通过队列也能解决,但有些场景我们对一致性的要求并不是最终一致,队列带来的消息可靠问题和时延以及剥离事务并不一定适用,因地制宜很关键”

    感谢,你这段话是真正的解决了我很大的一个困惑点,可能就是我们浅薄的业务里强一致场景几乎没有。
    benzalus
        84
    benzalus  
       205 天前
    看完帖子,学到不少。多线程自己写很少,用别人写的倒挺多
    rehoni
        85
    rehoni  
       205 天前
    楼主估计跟我一样,一直在做 to b ,难度都在业务上,而非技术上。所以工作上基本对多线程的应用场景根本没有多少需求==,当然多线程还是得学,就当满足自己的好奇心、个人提升,最终实现薪资提升 O(∩_∩)O
    wxlwsy
        86
    wxlwsy  
       205 天前
    极致压榨 CPU 性能需要多线程.
    现在各自框架搞起来显得多线程没啥用,但是本质还是多线程,只是框架替你做了而已.
    maigebaoer
        87
    maigebaoer  
       205 天前 via Android
    重计算的,用多线程和多 CPU 进行并行,比如图片视频处理;重 IO 的,任务关联度又不高,可以用单线程 Async EventLoop ,比如 http 请求
    chuck1in
        88
    chuck1in  
       205 天前
    这个其实是看体量的。

    如果你的项目业务比较大,用户比较,数据比较多,就很可能会用得上。
    甚至写代码的时候必须时时考虑这个问题,不然很容易就出生产事故了。

    如果你做的项目一般都是单机跑,功能上能用就行,这些其实就完全用不上。
    GraySoul
        89
    GraySoul  
    OP
       205 天前
    @rehoni 啊对 你说到点子上了,这么多年过去了,我总感觉我和别人不一样。。。他们都在说什么。。。面试都在面什么啊这是,然后就各种被人鄙视。。。讲道理论聪明才智,我觉得我也没说差很多啊,咋就同样做了这么多年,就我啥都不会呢。。。
    hzxxx
        90
    hzxxx  
       205 天前
    @tool2d BIO 不是阻塞 IO 吗? js 是异步 IO 模型,所以不会阻塞
    cp19890714
        91
    cp19890714  
       205 天前 via Android
    我现在的项目中经常用。如果不会用,就很难发现哪里需要用。
    很多人,说起来这些都懂,然而在业务开发中,逻辑都摆到面前了,他也没发现这里有并发问题。原因就是不懂,他所谓的懂,只是知道个皮毛。
    tool2d
        92
    tool2d  
       205 天前
    @hzxxx 我一直没搞明白,为什么网络需要设计成阻塞接口。

    非阻塞还能让代码继续干点的事情,一阻塞就什么都做不了了,只能傻等。
    leonshaw
        93
    leonshaw  
       205 天前
    @tool2d
    阻塞式接口更直观。重点不是等 IO 时让代码做别的事,而是让 CPU 做别的事。理想情况下,线程开销足够小,就可以一直创建线程调用阻塞接口。事件循环到协程的封装也是为了用阻塞式的逻辑写异步代码。
    pkupyx
        94
    pkupyx  
       205 天前
    锁的基本原理还是要理解,以及不加锁会出什么问题。
    分布式一致性的几种实现方式比锁重要。
    鸡架可能需要深入掌握一些小众的锁。
    blankmiss
        95
    blankmiss  
       205 天前
    @cloudzhou completefuture 同时干活来填充吗
    xuanbg
        96
    xuanbg  
       204 天前
    多线程不见得就要锁,只是多线程读写同一个数据需要锁。不是多线程很多时候也是有锁的,譬如数据库事务就是锁。

    多线程是为了充分利用 CPU 时间,而锁则是为了保证数据的一致性。两者并没有什么必然的联系。
    Narcissu5
        97
    Narcissu5  
       204 天前
    @tool2d 有没有这么一种可能,服务器有多个核
    nekoneko
        98
    nekoneko  
       204 天前
    比如说有一些资源, 一些线程会消费资源, 一些线程会添加资源, 消费添加的时候还有一些其他动作, 这时候不加锁你试试.
    nekoneko
        99
    nekoneko  
       204 天前
    比如说我有一亿条数据要处理, 每处理 100000 条需要调一个通知方法, 计数器要不要加锁, 调方法要不要加锁.
    leaves615
        100
    leaves615  
       204 天前
    你要求工资 2000 ,绝对没有这么多问题。
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   860 人在线   最高记录 6067   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 240ms · UTC 18:51 · PVG 02:51 · LAX 11:51 · JFK 14:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.