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

怎么设计一个线程安全的类?有什么原则吗?比如 vector?

  •  1
     
  •   FelixLiu · 2019-05-28 10:49:21 +08:00 · 3418 次点击
    这是一个创建于 2012 天前的主题,其中的信息可能已经有所发展或是发生改变。

    vector 基本每个方法都保证了原子性,但是组合起来也不一定。

    26 条回复    2019-05-29 09:13:25 +08:00
    Mithrandir
        1
    Mithrandir  
       2019-05-28 11:04:27 +08:00
    来把大锁就好了
    Mithrandir
        2
    Mithrandir  
       2019-05-28 11:04:55 +08:00
    如果是无锁数据结构,那比较复杂
    FelixLiu
        3
    FelixLiu  
    OP
       2019-05-28 11:18:08 +08:00
    @Mithrandir 来把大锁的话,还不如就设计成单线程模式,效率还是要提高一点的。。。
    mooncakejs
        4
    mooncakejs  
       2019-05-28 11:22:04 +08:00
    『大锁』
    读写锁
    分区锁
    COW+Immutable
    FelixLiu
        5
    FelixLiu  
    OP
       2019-05-28 11:26:17 +08:00
    @mooncakejs 我意思是有什么指导性原则吗?比如共享成员变量加锁之类的,实现可能很多种,事件、临界区、信号量。。。
    wysnylc
        6
    wysnylc  
       2019-05-28 11:58:41 +08:00   ❤️ 1
    首先 vector 只保证可见性不保证原子性,其次最安全的线程安全就是单线程参考实例 redis
    解决并发的最终方案只有队列
    tt67wq
        7
    tt67wq  
       2019-05-28 12:06:49 +08:00
    原子性的实现参考数据库事务的实现方法
    skypyb
        8
    skypyb  
       2019-05-28 12:09:51 +08:00 via Android
    线程最安全的就是不可变对象啦,你所有的属性包括类都是 final,就不用担心这问题了
    FelixLiu
        9
    FelixLiu  
    OP
       2019-05-28 13:39:38 +08:00
    @wysnylc 阔以,道路千万条,安全第一条
    FelixLiu
        10
    FelixLiu  
    OP
       2019-05-28 13:40:21 +08:00
    @skypyb 不可变对象。。。做不到哇
    FelixLiu
        11
    FelixLiu  
    OP
       2019-05-28 13:40:45 +08:00
    @tt67wq 我研究下
    CoderSun
        12
    CoderSun  
       2019-05-28 14:32:03 +08:00
    java 里临界区,锁,volatile,信号量,根据业务选择合适的。
    HuasLeung
        13
    HuasLeung  
       2019-05-28 14:36:29 +08:00
    自从用上了 go 语言的 goroutine,再也不用搞 java 线程中复杂的锁
    jimrok
        14
    jimrok  
       2019-05-28 16:14:50 +08:00
    干活的线程不要共享数据,干完了把数据交出去。
    sagaxu
        15
    sagaxu  
       2019-05-28 16:27:30 +08:00 via Android
    熟读 Java 并发编程实践这本书
    luozic
        16
    luozic  
       2019-05-28 16:30:49 +08:00 via iPhone
    去抄 jdk Dou 大佬的代码。
    momocraft
        17
    momocraft  
       2019-05-28 16:35:43 +08:00
    不能证明安全就是不安全
    自己写得越少 / 向外暴露 (包括 API,时机,可访问到的线程) 越少越容易做到安全
    FelixLiu
        18
    FelixLiu  
    OP
       2019-05-28 16:42:40 +08:00
    @HuasLeung 哈哈哈,最近我也在学 go
    FelixLiu
        19
    FelixLiu  
    OP
       2019-05-28 16:44:09 +08:00
    @jimrok 主要可能某个活比较重,需要派多个线程去干才能保证延迟。
    FelixLiu
        20
    FelixLiu  
    OP
       2019-05-28 16:45:32 +08:00
    @momocraft 精辟啊
    jimrok
        21
    jimrok  
       2019-05-28 17:01:37 +08:00   ❤️ 1
    @FelixLiu 要想安全就不要共享数据,并发的线程之间如果用到某些数据,保持只读访问或者把需要的数据打包起来,发给执行任务的线程,处理过程中,修改完数据后,再发送给另外的处理模块。
    23571113
        22
    23571113  
       2019-05-28 17:11:39 +08:00   ❤️ 1
    组合起来想达到原子性就等于套用数据库的事务原子性的那一套方法,推荐你看一下 2PL 方法。有些无锁(不需要加锁就可以线程安全)的数据结构可能也能满足你的要求,比如 BwTree 这种你可以了解一下。
    FelixLiu
        23
    FelixLiu  
    OP
       2019-05-28 17:21:47 +08:00
    @23571113 欧克,了解一波。
    mooncakejs
        24
    mooncakejs  
       2019-05-28 18:12:51 +08:00   ❤️ 1
    @FelixLiu 我理解:指导下原则就是资源特点和对性能的要求指标是什么。
    - 性能要求不高,来个大锁(对象锁)。
    - 读多写少,就来读写锁;
    - 读写均衡,可以来分区 /分段锁。
    - 资源为简单类型,atomic。
    - 对更改不敏感,COW & TheadLocal
    - 实时性邀请不高,外部队列。
    oneisall8955
        25
    oneisall8955  
       2019-05-29 01:26:43 +08:00 via Android
    @skypyb 还有这种说法?。。。
    FelixLiu
        26
    FelixLiu  
    OP
       2019-05-29 09:13:25 +08:00
    @mooncakejs 这个总结的挺好,简单明了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5456 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 06:53 · PVG 14:53 · LAX 22:53 · JFK 01:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.