并发控制总是必需的吗


当我们初次踏入Java的世界,初次学习线程的时候,有没有想过为什么要有这个东西?为什么我写了那么些年程序,好像根本就没有更多的使用到它那?

当JSR166随着Java5的发布而姗姗来迟的时候,为什么我们对它依然那么的一往情深?没有它,我们之前不也一样活吗?

当我们阅读过林林总总的讲并发编程理论和实践的书籍之后, 《JAVA并发编程实践 》 1 也好,《Java并发编程—设计原则与模式》2 也好, 这些书里的那些理论的本质是什么,它们又是不是放之四海而皆准那?

所有有关并发的介绍和理论,都是建立在什么东西的基础之上?如果我们仅仅局限在并发控制的世界之中(并非只是指Java的并发), 会不会有些“偏听则暗 ”之忧哪?

我们为什么需要并发控制?它能够帮助我们提高数据的处理速度,充分运用CPU? 或许这是一个方面,或者是表象,使用并发控制,最主要的一个原因,个人觉得,就是需要维护某个“共享 ”的数据状态的完整性。 也就是说,是否存在共享的数据状态,决定着我们是否需要引入并发控制。

  • 如果存在共享的数据状态,并且,又有多个“人 ”(Thread)要对这一共享的数据状态进行更新操作, 那么,为了保证其状态的完整性和正确性,我们就必须引入并发控制; 反之,如果这些“人 ”(Thread)仅仅只是读这一共享的数据状态,没有任何的更新操作,那并发的引入则是没有必要的。
  • 如果没有共享的数据状态,通常意味着每个人(线程)有自己的数据拷贝,那么,你爱怎么折腾怎么折腾,引入并发控制一点儿意义都没有。

从某个角度来说,并发控制可以分为两种:

  • 乐观型策略. 这种策略通常应用在并发性不是很高,并发强度为中低档水平的时候,比如STM(Software Transaction Memory)或者CAS(Compare and Swap/Compare and Set)这些理念或者实现方式。
  • 悲观型策略. 这种策略通常应用在高并发性场合,因为这种情况下,这种策略要比乐观型策略获得更好的效果。像Lock和Synchronization就属于这种情况。

实际上,你完全可以用数据库的乐观锁和悲观锁来类比并推演出这两种策略。 既然并发控制的存在是因为存在共享的数据状态,那么避免甚至移除这些共享的数据状态是不是就意味着能够避免并发,甚至前进到并行处理的世界那? More or less, I think.

当提到Thread confinement的时候,或者更具体一些,提到ThreadLocal的时候, 我们是不是马上就能想到,它不就是通过为每个人(线程)分配不同的数据拷贝而避免了并发控制嘛! Erlang的书买了还没看,不过,他的share-nothing的理念不正是他能够在并行处理的世界里自由驰骋的保证吗?

share something, or share nothing, 这才是并发存在与否的前提,不是吗?

P.S. 并发与并行计算绝对不是我这么几句闲扯就能囊括过来的,哪位要是有兴趣可以从其它角度来阐述这个问题(比如硬件的角度),俺们都洗耳恭听中,呵呵


  1. 英文名《Java Concurrency in Practice》↩︎

  2. 英文名《Concurrent Programming in Java Design Principles and Patterns》↩︎


>>>>>> 更多阅读 <<<<<<


欢迎加入「福强私学」

跨越2190个日夜,始终坚持“实践 + 原创”打造的715125字专属知识库,囊括了(但不限于)从职场、技术、管理与商业等多个板块的内容。

  • 一个ChatGPT触达不到的地方
  • 一个带你超越AI/人工智能的地方
  • 一个与你一起成长的地方

https://afoo.me/kb.html


开天窗,拉认知,订阅「福报」,即刻拥有自己的全模态人工智能。

订阅「福报」