【GWA2 Java 增加多线程数据共享通道 globalData】令举国民众震惊的江苏徐州丰县铁链女(生育八孩女子)一事逐渐被消音( https://ufqi.com/news/ulongpa...仍留下徐州丰县生育八孩女子独自面对命运|舆论手札 ),今暂且不论。
GWA2 Java 最近被部署到一个金融类项目( 有福金融:https://ufqi.com/finance )上运行之后,持续遇到并发、数据同步、多进程多线程数据访问控制的挑战。在此前一篇的博客中,我们讨论了在数据同步时的数据加锁的过程细节:Synchronized同步Quque队列Concurrency并发与线程锁Lock ( https://ufqi.com/blog/gwa2-ph... )。 今天继续这个话题,讨论 GWA2 Java 寄宿于 Apache Tomcat中多进程多线程编程及运行时环境下,如何实现对多线程间数据的隔离与共享。
前文记述,在Apache Tomcat 等容器中,实现对数据的安全管控的最好的方式是使用 Synchronized 同步机制,让程序单线程运行,但这很难在Application层面扩展处理能力。于是我们修改了规则,默认不再启用 synchronized同步机制在全局。这样 GWA2 Java 重新回到多进程多线程运行环境,并发扩展能力激增。随之而来的就是在多线程运行时环境下,数据的隔离与共享。
有些数据是需要隔离的,比如在多线程并发运行时环境下,当请求1被线程A接管的同时,请求2被线程B接管,如果不做数据隔离的话,在整个进程中的数据都会被重置为较后者进来的请求。
我们需要某种机制将请求的各种数据限制在线程内。
同时,有些数据又需要被共享,一个接口或进程启动后,总有一些全局性的设置或变量,需要能够在所有线程中被访问到。这又要求我们必需提供某种机制能够满足,在多线程环境下,对一些全局数据的读写访问,并保障这些数据是线程安全的(Thread-Safe)。
文章图片
fig1.单线程与多线程运行时状态示意图
在一番分析和探索之后,我们对GWA2 Java做了如下改进和升级,以实现GWA2 Java从 “线程不安全—单线程安全—多线程安全” 的演进。
1/3. 改进全局数据容器data的类型:用ConcurrentHashMap取代HashMap
脱胎于GWA2 PHP,我们始终认为需要一个全局性的数据容器,可以将任务/业务处理过程中所产生的数据临时存放起来,这个数据容器无疑类型是一个字典表之类。在GWA2 Java中,起初使用了 HashMap(非线程安全的),后来遇到数据同步问题后,使用Synchronized同步关键词得以临时解决。
再次的探索研究,我们认为是时候使用 ConcurrentHashMap替代HashMap 了,ConcurrentHashMap 对多线程有更好的支持,而且是Java原生的数据类型。
代价也是有的,毕竟ConcurrentHashMap在数据读写时,要处理线程锁的问题,因为在数据处理上开销更大,速度稍慢。
另外令人不好接受的是,ConcurrentHashMap不接受null空值,key或者value,都不行,这无疑对于痛恨Java null的开发者来说,将会更加多地要注意,存储data数据时,需要考虑到是否null的前置判断。
....
全文原发: https://ufqi.com/blog/gwa2-ja... , -R/22SU