在之前的文章讨论了 数据可见性 问题,说的主要是一些理论上的东西,比较的抽象,下面来说一个简单的模型吧:
很多地方我们需要用一个容器来保存一些实体,如果这个容器内的实体经常的变化(添加或删除),那么要保证这个容器的线程安全将会变得比较棘手(如果更新相对比较少,且注重读取的性能,那么可以用CopyOnWriteArrayList); 其实往容器中添加信息倒还好,但删除就会比较麻烦,影子模型就是为了避免删除这一个动作的:
把实体放到一个封装类中(把这个封装类叫做实体的影子),在里面有一个标志位,表示这个被包装的实体是否有效,当要删除这个实体时,就把这个标志位设置为无效(并不实时从物理上将这个实体从容器中删除)(表示旧的影子已经失效了)(可以将用户的影子作为用户信息保存起来,这样就不用去遍历实体容器寻找旧的影子);关于如何保证该标志位的可见性问题,其实只要将其设置为volatile即可(在一些并不要求强可见性的场合,可以根据“并发闲聊 – 数据可见性”的延伸解读2或者3来尽量保证它的可见性)。
单单看影子模型部分的其实是一个非常简单的封装想法,这里就直接上代码吧:
影子接口:
影子的标准实现类:
影子的弱化版实现类:(可以根据“并发闲聊 – 数据可见性”的延伸解读2或者3来尽量保证它的可见性)