有一天,java遇到了python兄弟,调侃道:“我听一位刚学python的老伙计道,你这并发包很不好用呀。”
“怎么不好用了,我有Threading模块,只要创建一个Thread实例,调用start()就可以了,而且我的线程是真正的Posix Thread,这可是操作系统级的呀。”python道。
java道:“这年头,许多语言用的都是内核线程,谁还用模拟线程,用户线程呀,你这个特性也没什么起眼的,你多线程最致命的一点就是没法使用多核优势,在四核,八核的的cpu下多线程跑,依然只用了一核,白白浪费了人家的高性能呀。”
python脸红红地,争辩道:“这又不是独独我一门语言的过失,底层平台也有关系,我用的cpython解释器执行代码时,有一个GIL(Global Interpreter Lock)锁,Python线程执行前,必须先获得GIL锁,然后,每执行一段字节码,解释器就自动释放GIL锁,别的线程才有机会执行。这个GIL全局锁把所有线程的执行段都给上了锁,所以,多线程在Python中只能交替执行。这是CPython解释器的问题”
“那就赶快转移到我们JVM平台吧,你的兄弟Jython就很识相,他用的就是我们jvm的线程机制,没有那个问题!”
“你们平台也不是没任何问题,用了jython,是否就意味着失去了利用我们社区众多C模块库的机会,这对程序员哥哥而言可是大大的不友好啊。要想发挥多核优势,我也不是不可以,你要知道,除了多线程,还有多进程,我们的多进程编程也是十分方便的,multiprocessing提供了跨平台的多进程支持,还可以通过Pool批量创建进程,利用Queue,Pipes进行进程间通信。”
“多进程早就有了,但为什么后来还要引入多线程呢,还不是因为多进程有诸多缺陷。多进程产生更多的系统开销,当进行上下文切换的时候,进程记忆的所有内存地址都会失效,而线程切换的时候,用的是同一份虚拟内存空间。进程间通信也更为繁杂,需要用Queue put和get操作,如果是多线程,则共享所在进程的各种资源,只要声明一个全局变量,并通过加锁等方式保证线程安全就可以。”
“呵呵,轻描淡写,在并发环境下的编程就没有容易的。cpython未来将会有计划地移除CGL的,我们的生态前景还是十分光明的,最重要的是,我们应用范围比你要广,可以说是全能的运动员,在数据处理,网络爬虫,DevOps领域,却少见你们的身影。”
“咱现在比的是并发领域的处理方式。别跑题了,兄弟!” java道。
开发过程中一个异常问题探讨:
前端服务器利用nginx进行反向代理,后台配的是两个jetty服务,jetty里的webapp用的是spring boot,模版引擎用的是velocity,controller层有一些方法,在跳转之前设置了参数,如:
redirectAttributes.addFlashAttribute("isSuccess",true);
redirectAttributes.addFlashAttribute("msg",message);
return "redirect:/list";
当nginx location配置如下时:
location /myapp{
proxy_pass http://servicename/myapp/;
break;
access_log logs/$host.log_servicename main; }
返回的列表页面在客户端没有isSuccess,msg两个参数信息展示,但如果新加一个location配置,就有了,只是加了个斜杠:
location /myapp{
proxy_pass http://servicename/myapp/;
break;
access_log logs/$host.log_servicename main; }
location /myapp/{
proxy_pass http://servicename/myapp/;
break;
access_log logs/$host.log_servicename main; }
为什么会这样,有什么想法请留言?
java达人
ID:drjava
(扫码或长按识别)
领取专属 10元无门槛券
私享最新 技术干货