影子模型(Java篇)

本文介绍了一种解决线程安全问题的影子模型,主要应用于需要频繁添加和删除实体的容器。通过创建实体的影子并使用volatile确保标志位的可见性,避免了实体删除时的同步问题。影子模型简化了并发编程中的线程安全处理,文中给出了具体的代码实现,包括影子接口、实现类以及一个用户加入和退出房间的场景应用示例。
摘要由CSDN通过智能技术生成


在之前的文章讨论了 数据可见性 问题,说的主要是一些理论上的东西,比较的抽象,下面来说一个简单的模型吧:


很多地方我们需要用一个容器来保存一些实体,如果这个容器内的实体经常的变化(添加或删除),那么要保证这个容器的线程安全将会变得比较棘手(如果更新相对比较少,且注重读取的性能,那么可以用CopyOnWriteArrayList); 其实往容器中添加信息倒还好,但删除就会比较麻烦,影子模型就是为了避免删除这一个动作的:


把实体放到一个封装类中(把这个封装类叫做实体的影子),在里面有一个标志位,表示这个被包装的实体是否有效,当要删除这个实体时,就把这个标志位设置为无效(并不实时从物理上将这个实体从容器中删除)(表示旧的影子已经失效了)(可以将用户的影子作为用户信息保存起来,这样就不用去遍历实体容器寻找旧的影子);关于如何保证该标志位的可见性问题,其实只要将其设置为volatile即可(在一些并不要求强可见性的场合,可以根据“并发闲聊 – 数据可见性”的延伸解读2或者3来尽量保证它的可见性)。






单单看影子模型部分的其实是一个非常简单的封装想法,这里就直接上代码吧:

影子接口:

package com.dc.util.shadow.shadow;
/** 
 * 影子对象接口 
 * @author Daemon
 * @param <Entity> 影子的实体
 */
public interface IShadow<Entity> {
    
    /**
     * 影子有效
     */
    void valid();
    
    /**
     * 影子失效
     */
    void invalid();
    
    /**
     * 影子是否失效
     * 
     * @return 影子是否失效
     */
    boolean isvalid();
    
    /**
     * 获得影子的实体
     * 
     * @return 影子的实体
     */
    Entity getEntity();
}


影子的标准实现类:

package com.dc.util.shadow.shadow.nomal;
import com.dc.util.shadow.shadow.IShadow;

/** 
 * 影子(通过将isvalid声明为volatile确保其可见性) 
 * @author Daemon
 * @param <Entity> 影子的实体
 */
public class Shadow<Entity> implements IShadow<Entity> {

    /**
     * 影子是否有效
     */
    protected volatile boolean isvalid;
    
    /**
     * 影子的实体
     */
    protected final Entity entity;
    
    public Shadow(Entity entity) {
        this.entity = entity;
        isvalid = true;
    }
    
    public Shadow(Entity entity, boolean isvalid) {
        this.entity = entity;
        this.isvalid = isvalid;
    }
    
    public void valid() {
        isvalid = true;
    }

    public void invalid() {
        isvalid = false;
    }
    
    public boolean isvalid() {
        return isvalid;
    }
    
    public Entity getEntity() {
        return entity;
    }
    
}


影子的弱化版实现类:(可以根据“并发闲聊 – 数据可见性”的延伸解读2或者3来尽量保证它的可见性)

package com.dc.util.shadow.shadow.week;
import com.dc.util.shadow.shadow.IShadow;

/** 
 * 弱可见性的影子(属性isvalid可见性无保证) 
 * @author Daemon
 * @param <Entity> 影子的实体
 */
public class WeekShadow<Entity> implements IShadow<Entity> {

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值