JLS定义的‘correctly synchronized’能否应用于类而非整个程序?
先明确Java语言规范(JLS)中对correctly synchronized的定义:
当且仅当所有顺序一致的执行均无data races时,程序才是correctly synchronized的。
若程序是correctly synchronized的,则该程序的所有执行都将表现为顺序一致。
能否将该概念应用到更小单元(比如自定义并发集合类)?
JLS的定义本质是针对整个程序的,但我们可以把类似的逻辑延伸到线程安全组件上:我们可以设计并发集合类,使其自身实现满足——只要使用者遵循约定(只通过类的公共方法访问状态,不直接操作内部未同步的共享变量),那么无论这个集合被用到哪个程序里,其内部操作都不会产生data races。不过这和JLS定义的“整个程序的correctly synchronized”不是一回事,因为整个程序的正确性还依赖于组件间的交互是否符合同步规则,但组件自身可以做到“内部无data races”的线程安全承诺。
仅检查顺序执行无data races,能保证并发执行也无吗?
绝对不行。
顺序执行是串行的,不存在多线程同时访问共享状态的场景,自然不会有data races。但并发场景下线程操作是交错的,如果集合内部没有用正确的同步机制(比如锁、volatile、原子类等)约束共享状态的访问,哪怕顺序执行没问题,并发时依然会出现data races。举个例子:两个线程同时对未加锁的共享计数器做自增,顺序执行结果正确,但并发交错时会因为读写重叠导致数据错误,这就是典型的data race。
要保证组件在并发下无data races,必须确保所有对共享状态的读写都被正确同步:比如所有修改和读取共享状态的方法都持有同一个锁,用volatile保证变量的可见性和有序性,或者用原子类保证操作原子性。这些同步措施才能让组件的并发执行符合JLS的同步规则,避免data races,而不是只看顺序执行的情况。
内容的提问来源于stack exchange,提问作者JJJ

