python 和 ruby 都有 GIL,但是好像一些其他语言没有 GIL,请问其他语言(比如 java)如何处理这个问题的?是所有库都有 lock 保证资源安全吗?
不是 python, ruby 有 GIL,而是 python 的最流行的解释器 cpython 和 ruby 的最流行的解释器 mri 都实施了 GIL .
解释器中实施 GIL 与否是个设计决定,选任何一个都要做出些妥协,具体可以搜搜看。
JVM 没有 GIL,但是也有锁,只是锁的粒度细小得多,一般不会整个线程给你锁上。
楼主是想问 java 中 synchronized 这东西的么?
jvm 的锁优化做的远胜 ruby,python,种类多,偏向缩,可重入锁,7 里面的并发库加入以 cas(compare and swap)实现的解决锁开销问题也是一大亮点,也是为了适应多核环境,ruby python 主流解释器无法完全开发多核性能。相应的,设计复杂度上就高出几个数量级。
主要是 Java 有金主,有人撑腰
java 是对象锁,而且 java 很少在运行期进行对象的修改,但 ruby 这种动态语言可以在运行期进行类的修改。
以我阅读《Seven Concurrency Models in Seven Weeks》第一章了解到的,Java 线程需要程序员处理的问题一样有,然后作者再三强调用锁很容易出错,推荐用其它并发/平行模型。
JRuby 实现据说可以没有 GIL
GIL 是个伪命题 ——初级程序员很容易被 80 年代的中文翻译过来的垃圾过时教程说,解决 concurrency 只能用多线程。然后就拿着多线程这个锤子到处找钉子。
其实这里要区分一个 IO 密集和 CPU 密集的,IO 密集,即便有 GIL 也可以通过 coroutine 或者 Fiber 很好解决,性能不低。
CPU 密集——这个得好好想一下。
所以 GIL 不是不能用多线程问题,而是多线程只能用单个核心的问题。但是实际上,大家也不是没见过 Chrome 啊,3D 游戏里只把一个核心占满的情况。这不就是只能利用一个核心的毛病么?为啥 GIL 就臭名昭著,而 C/C++ 大家就会很自然想到一个借口说你代码写得不好呢?
但是反过来说,你要用脚本语言解决计算密集问题?你 TM 逗我?计算性能问题,首先就得说 MRI/CPython 这个和 C 语言 30 倍性能差距的问题。。。。。。。。。。
就算没 GIL 的 Java 里,写多线程也不是个什么好体验。JVM 是不会卡进程,各种锁得你自己搞。搞得不好还是会卡进程。就算 C/C++ 直接用 pthreads,写起来是各种坑。
在实际应用中,GIL 给大家带来的不便是 0。绝大多数市面上能看到的多线程教程,无论什么语言,都是用来解决 io wait 的问题的。io wait 在 Ruby/Python 已经有 n 种解决方案了。
你如果写代码真碰到 GIL 问题了,请一定怀疑你的姿势不对。
自后还是要喷一下:为什么 nodejs 没有 GIL 问题?因为别人压根不支持多线程。(还不是活得好好的。)