多线程开发是 Java 语言中经常用到的(别说你不用)....
当我们谈论多线程的时候总有一个讨论点 : 线程安全. 当我们谈论线程安全的时候我们在谈什么? 什么原子性\可见性\顺序性\锁\同步\CAS\xx 原则\volatile 语法\jdk 的新库\vector 与 arraylist 哪个安全\面试考题等等等等....
SO...
妈蛋,能不能先把 JDK 中成百上千个类中,哪些不是线程安全的给苦逼的程序员标注出来先? 原罪啊... 老司机都表示不淡定了...
![]() | 1 enenaaa 2017-02-23 17:11:30 +08:00 把你不确认的都当成非线程安全 |
![]() | 3 linbiaye 2017-02-23 17:17:19 +08:00 线程安全的不都给你放 java.util.concurrent 下面了么。 |
![]() | 4 skywayman OP @linbiaye 话是没有错,但你要用 SimpleDateFormat,用 StringBuilder 嘛... |
5 kappa 2017-02-23 18:02:37 +08:00 @skywayman RTFM Synchronization Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally. 或者继续当韭菜,也方便筛人 |
![]() | 6 mokeyjay 2017-02-23 18:28:37 +08:00 via Android 问:程序猿为何要使用多线程? 答:因为他们觉得生活还不够乱 |
7 xuyankang 2017-02-23 18:31:36 +08:00 线程不安全的类也能线程安全,线程安全的类也能线程不安全。。。 |
![]() | 8 hepin1989 2017-02-23 19:54:44 +08:00 能力问题 |
9 kaneg 2017-02-23 19:58:39 +08:00 via iPhone Java 的多线程设计是相当优雅的,觉得不安全就加 synchronized ,没有那么可怕。 |
![]() | 10 ihuotui 2017-02-23 21:08:57 +08:00 via iPhone 因为场景太多,只是你见识少,例如在多线程下同一个 id 的操作线程要求顺序,使用 lock 的公平锁。 |
![]() | 11 ovear 2017-02-23 21:11:16 +08:00 那啥。。要怕的话可以直接加一个 synchronize 出了效率问题,或者有时间再弄。。 |
![]() | 12 Sight4 2017-02-23 21:29:15 +08:00 线程安全这个问题不是 Java 独有的吧.... |
13 tianice 2017-02-23 21:56:12 +08:00 jdk 有很多问题,基本都是要兼容旧版本导致的,早就该改改了 |
![]() | 14 hjc4869 2017-02-23 21:58:14 +08:00 原则上文档 /标准中没有说线程安全就代表实现时没必要保证线程安全,也就是你不能当线程安全的用。 |
![]() | 15 gouchaoer 2017-02-23 22:11:41 +08:00 via Android java 的多线程做的很好了,你居然还不满足 |
16 gam2046 2017-02-23 22:18:04 +08:00 Windows 原罪..... 装软件是 Windows 中经常用到的(别说你不用).... 当我们谈论装软件的时候总有一个讨论点 : 有没有病毒. 当我们谈论病毒的时候我们在谈什么? 什么 360\杀毒软件\主动防御\HIPS\安全管家\安全助手等等等等.... SO... 妈蛋,能不能先把 Windows 中成千上万的软件中,哪些没有病毒的给苦逼的用户标注出来先? 原罪啊... 老司机都表示不淡定了... |
![]() | 17 icebergSnow 2017-02-23 22:26:11 +08:00 via Android 不太懂你,病毒又不是微软产的 |
![]() | 18 skywayman OP @gam2046 亏你打这么多,本质没理解. JDK 是原生的,直接给开发人员使用的,病毒是 windows 中原生的嘛? 明明是第三方编写并传播的,要反思的是 windows 的内部机理吧... @gouchaoer 不是不满足,只是不明白既然引入了多线程,为什么不把基础类库做的更好一点,比如编译的时候能识别某基础类库在多线程环境下会有问题,出现个警告之类的....而不用人去"趟坑",然后把结果和过程称之为"开发经验"或"血泪教训"; @hjc4869 基础类库是不是太多了点,我反正没有全部看完 @tianice 知音 @Sight4 我并不是抱怨线程安全问题 @hepin1989 我水平一般 @xuyankang 这是实话 @kappa 其实只是不明白既然引入了多线程,为什么不把基础类库做的更好一点,比如编译的时候能识别某类库在多线程环境下会有问题,出现个警告之类的....而不用人去"趟坑",然后把结果和过程称之为"开发经验"或"血泪教训"; |
![]() | 20 Allianzcortex 2017-02-23 23:52:57 +08:00 via iPhone joda-time 和 stringbuffer |
![]() | 21 mikulch 2017-02-24 00:02:25 +08:00 楼主之前写啥语言的。 |
![]() | 22 ovear 2017-02-24 00:06:11 +08:00 @skywayman 线程安全是跟程序员的设计有关 并不是说类库在多线程情况下就一定有问题。而是可能出现意料外的情况,但是在正确的设计中,即使是多线程环境,一些所谓的非线程安全的类库也不会产生 意料外 的情况。而这时候编译器抛出 warning 就有点。。。了 所以这个属于业务逻辑问题,锅在程序员,跟编译器关系不大。 |
![]() | 23 skywayman OP @ovear 那什么是正确的设计?把线程安全的方方面面都全部搞懂后设计出来的程序就是正确的设计了?很多业务复杂的多线程环境,基础类库经常出现隐性的深层次问题,调起来非常的伤神.这个不否认吧. 我觉得出 warning 多好,即能淘汰旧 api,也能迫使开发人员知识体系升级,还减少出错,一举多得! |
![]() | 24 ovear 2017-02-24 00:24:04 +08:00 @skywayman 所以你也说了,这是“你觉得” 同步不是百利而无一害的,它是有代价的,这是由程序员自己决定的,是否使用读同步,写同步。这些都是有代价的。 打个比方,在外部条件的约束下,也许是多线程中使用非线程安全的类库,但是却能保证不出问题 再打个比方,一个数据结构中,多个线程共用,但是每个线程负责不同的部分。此时有使用读写同步的必要么。 诸如此类的情况太多了,这应该是程序员去关心的业务具体展示,而不是编译器关心你的算法 |
![]() | 25 ovear 2017-02-24 00:28:38 +08:00 ![]() @ovear 而且更重要的是,所谓官方的线程安全,很可能跟你业务所需要的线程安全,是有差异的。类库的线程安全是不能实现你需要的效果的。 最简单的比方 public static void main(String[] args){ while(true){ for(int i = 0; i<10; i++){ vector.add(i); } } //一个线程删数据 Thread removeThread = new Thread(new Runnable(){ @Override public void run(){ for(int i=0 ; i<vector.size() ;i++){ vector.remove(i); } } }); //一个线程读数据 Thread printThread = new Thread(new Runnable() { @Override public void run(){ for(int i=0 ; i<vector.size() ;i++){ System.out.println(vector.get(i)); } } }); removeThread.start(); printThread.start(); //防止过多线程,内存溢出 while(Thread.activeCount() > 20); } 上述代码就会产生意料外的情况,那么 Vector 是非线程安全的么? 代码来自: https://zhuanlan.zhihu.com/p/21339889 |
![]() | 26 zhuangzhuang1988 2017-02-24 00:58:08 +08:00 题主想法是好的 在 《 Java 并发编程实战》这本书中就大量使用了这个方法使用的是标注,附录中也有详细描述 |
![]() | 27 bombless 2017-02-24 02:06:23 +08:00 via Android 经常是这样的:除非特别说明,都是线程不安全的。 来我们 rust 吧,仍然是除非特别说明都是线程不安全的。不过我们的线程安全在类型中被标出来了,因此编译器会检查一些情况,比如数据竞争。 |
![]() | 28 des 2017-02-24 07:54:08 +08:00 via Android @bombless 主要还是怕踩坑。好的设计当然是不用说的。 打比方来说 c 里面有个根据 DNS 获取 ip 的 API ,就有线程不安全版的,如果没有标注的话,就直接掉进去了,总不能所有东西都加锁吧? |
![]() | 30 Citrus 2017-02-24 08:04:55 +08:00 via iPhone @ovear 虽然你说的没错,但是感觉你有点曲解了楼主的意思_>感觉楼主只是想方便快捷的知道哪些是线程安全的哪些不是而已,这样就不用用个啥就提心吊胆的吧~ |
32 zacard 2017-02-24 09:16:25 +08:00 在多线程环境中,非线程安全的类不一定就有问题啊。。。。 |
![]() | 33 ovear 2017-02-24 09:50:54 +08:00 @Citrus 自动完成以及提示 比如说 NetBeans 可以按住 ctrl 和类的名字看当前类的注释,一般线程安全和非线程安全都是用粗体字标记,应该已经够简单了吧=。= 我只是认为,这个操作不应该由编译器进行 warning |
![]() | 34 pangliang 2017-02-24 10:18:16 +08:00 楼主应该去写 rust |
35 m8syYID5eaas8hF7 2017-02-24 10:25:35 +08:00 只能慢慢适应。其实看一下源代码很快就可以判断是不是线程安全的嘛 |
![]() | 36 skywayman OP |
37 zhzy0077 2017-02-24 10:55:27 +08:00 via Android 可是编译器怎么知道你这个 ArrayList 会不会用在多线程环境中。。如果就用 ArrayList 存数据,不去修改的话,事实上这个 ArrayList 也是线程安全的,编译器也要告警应该用 Vector ? |
38 jaxonHu 2017-02-24 10:59:29 +08:00 《多处理器编程的艺术》 |
![]() | 39 sagaxu 2017-02-24 11:20:12 +08:00 没写安全的,就是不安全的,即时某个版本实现的安全,也可能随时改变。 |
40 WhoMercy 2017-02-24 11:43:02 +08:00 Junior Coder :这什么辣鸡编译器(IDE),怎么不把所有老司机约定成俗的东西都提示出来(我又不是老司机),使用的时候又不想看文档,也从不看源码,你不提示我怎么知道,是不是看我掉坑里很开心?? 这辣鸡*DK ,你只要告诉我怎么用就好了嘛,最好再带上几个不同版本的业务示例。 开心就好 |
41 youxiachai 2017-02-24 11:54:55 +08:00 lz 还是太懒了... 当年..我学 java 的时候....一个月(闲时)把所有类包看完.... |
![]() | 42 skywayman OP @WhoMercy :) 可能开源就是这德行吧... @youxiachai 皇上,还记得当年湖畔的夏雨荷 JPEGHuffmanTable 是不是安全的? @zhzy0077 =和==都知道,何况 thread 和 runnable 上下文环境,编译器肯定有办法,再者换成 vector 也不是错啊,哪天业务变更,说不定 vector 更安全不是? |
![]() | 43 xianyu0 2017-02-24 12:51:12 +08:00 关 JDK 什么事,这是 JVM 的事吧 |
44 zhzy0077 2017-02-24 13:01:06 +08:00 via Android 1. 要是编译器这个都知道,就能帮你在可能发生 race condition 的地方自动加锁了,显然是不可能的。 2. 那按照你的说法, JDK 不用 ArrayList 了?大家一起用 Vector ? |
![]() | 45 AntiGameZ 2017-02-24 13:09:51 +08:00 @WhoMercy IDE 就应该尽最大可能去辅助程序员,这没有什么不对。如果能够有办法让人不看文档不搜索就很容易的根据 context 给出提示/警告/报错,不正应该是工具要去做的事情么? 觉得 LZ 说的有理,那么多冷嘲热讽偏离主题的... |
![]() | 46 xmh51 2017-02-24 13:15:02 +08:00 ide 真达到这种底部,还要程序员干啥? |
![]() | 47 sheep3 2017-02-24 14:50:26 +08:00 单纯的能力问题,你觉得要怎么告诉你哪些安全哪些不安全才行? doc 上面写着够不够? |
![]() | 48 Khlieb 2017-02-25 17:54:01 +08:00 via Android Java 有两大开发工具,一个叫 JDK ,一个叫 OpenJDK |