并发编码模式

编程入门 行业动态 更新时间:2024-10-12 08:20:59

并发编码<a href=https://www.elefans.com/category/jswz/34/1771241.html style=模式"/>

并发编码模式

    解决线程处理共享数据除了之前的线程变量(ThreadLocal)和不可变(Immatable)模式外,还有一个方式就是CopyOnWrite模式(也叫COW ),但是有自己的适用场景。针对该模式 java juc提供了 CopyOnWriteArrayList、CopyOnWriteArraySet(底层使用CopyOnWriteArrayList保证去重实现)。

一、使用场景

1、读多写少

2、数据量比较小

3、对数据的一致性要求不是非常的高

二、原理

    读数据:直接进行读取

    写数据:将原数据进行Copy,再进行修改(所以需要一致性要求数据量比较小),最后将原对象的属性指向修改后的数组地址;

所以当并行修改和查询时,可能查询到旧数据(所以需要一致性要求不是特别高

三、CopyOnWriteArrayList源码(其他方法与add类似)

public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializable {private static final long serialVersionUID = 8673264195747942595L;final transient ReentrantLock lock = new ReentrantLock();private transient volatile Object[] array;private static final Unsafe UNSAFE;private static final long lockOffset;
}
public boolean add(E var1) {// 有修改时,先加锁(所以最好读多写少场景)ReentrantLock var2 = this.lock;var2.lock();boolean var6;try {Object[] var3 = this.getArray();int var4 = var3.length;// 先Copy再修改Object[] var5 = Arrays.copyOf(var3, var4 + 1);var5[var4] = var1;// 最后设置新值this.setArray(var5);var6 = true;} finally {var2.unlock();}return var6;
}

四、使用场景实例

    比如微服务去定时去获取服务请求列表信息时,如:Ribbon等服务列表,就比较适用该场景。数据一致性要求不是很高,数据量比较小,读多写少。

demo数据结构如: ConcurrentHashMap<String, CopyOnWriteArraySet<Router>>


//路由信息
public final class Router{private final String  ip;private final Integer port;private final String  iface;//构造函数public Router(String ip, Integer port, String iface){this.ip = ip;this.port = port;this.iface = iface;}//重写equals方法public boolean equals(Object obj){if (obj instanceof Router) {Router r = (Router)obj;return iface.equals(r.iface) &&ip.equals(r.ip) &&port.equals(r.port);}return false;}public int hashCode() {//省略hashCode相关代码}
}
//路由表信息
public class RouterTable {//Key:接口名//Value:路由集合ConcurrentHashMap<String, CopyOnWriteArraySet<Router>> rt = new ConcurrentHashMap<>();//根据接口名获取路由表public Set<Router> get(String iface){return rt.get(iface);}//删除路由public void remove(Router router) {Set<Router> set=rt.get(router.iface);if (set != null) {set.remove(router);}}//增加路由public void add(Router router) {Set<Router> set = rtputeIfAbsent(route.iface, r -> new CopyOnWriteArraySet<>());set.add(router);}
}

 

 

 

 

更多推荐

并发编码模式

本文发布于:2024-02-27 14:07:23,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1706837.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模式

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!