【Java项目】多文件传输:资源注册中心@资源拥有者池

该篇主要完成,资源节点添加、删除、获取资源节点地址列表。

1、设计目的

注册中心存储资源节点信息,以便向发送端提供服务地址列表。

2、主要功能
  1. 资源拥有者,向注册中心注册资源。
  2. 发送端向注册中心报告健康值状况。
  3. 注册中心,向接收端提供服务地址列表。
3、资源拥有者池
  1. 服务地址列表
 private static final Map<Integer, List<Node>> ownerPool;

key:资源id
value:服务地址列表。

  1. 接收端注册
 private static final Map<Integer, ResourceNodeInfo> nodePool;

key : 资源网络节点hashcode;
value:资源节点信息。

  1. 资源节点信息ResourceNodeInfo
package man.kuke.registry;

/**
 * @author: kuke
 * @date: 2020/12/5 - 21:57
 * @description:
 */
public class ResourceNodeInfo {
    private Node node;
   //用于记录资源网络节点地址及注册的资源个数。
    private int resourceCount;

    public ResourceNodeInfo(Node node) {
        this.resourceCount = 0;
        this.node = node;
    }

    public ResourceNodeInfo() {
    }

    public Node getNode() {
        return node;
    }

    public void setNode(Node node) {
        this.node = node;
    }

    public int getResourceCount() {
        return resourceCount;
    }

    public int deCount() {
        return resourceCount--;
    }

    public int incCount() {
        return resourceCount++;
    }
	//设置资源节点健康值
    public void setHealth(int health) {
        node.setHealth(health);
    }
}

  1. 资源拥有者池
package man.kuke.registry;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: kuke
 * @date: 2020/12/5 - 19:19
 * @description:
 */
public class ResourOwnerPool {
    /**
     * 资源拥有者
     * 这里增加资源拥有者节点
     * map键值对添加存在线程安全
     * list 生成存在线程安全。
     * list 多线程增加节点存在安全
     * key = 资源id
     */
    private static final Map<Integer, List<Node>> ownerPool;
    /**
     * 节点信息
     * map键值对添加存在线程安全
     * ResourceNodeInfo 生成存在线程安全
     *  key = (node.port + node.ip).hashcode
     */
    private static final Map<Integer, ResourceNodeInfo> nodePool;
    private static final Object resourceNodeInfoLock;
    private static final Object listLock;

    static {
        ownerPool = new ConcurrentHashMap<>();
        nodePool = new ConcurrentHashMap<>();
        resourceNodeInfoLock = new Object();
        listLock = new Object();
    }

    public ResourOwnerPool() {
    }

    private ResourceNodeInfo checkAddress(Node node) {
        return nodePool.get(node.hashCode());
    }
    
    //获取发送端节点信息
    private ResourceNodeInfo checkAndGetAddress(Node node) {
        Integer nodeHashCode = node.hashCode();
        ResourceNodeInfo orgNode = nodePool.get(nodeHashCode);
        if (orgNode == null) {
            synchronized (listLock) {
                orgNode = nodePool.get(nodeHashCode);
                //该两个操作应为原子性
                if (orgNode == null) {
                    orgNode = new ResourceNodeInfo(node);
                    nodePool.put(nodeHashCode, orgNode);
                }
            }
        }
        return orgNode;
    }


    //注册资源
    void addResource(Integer resourceId, Node node) {
        ResourceNodeInfo nodeInfo = checkAndGetAddress(node);

        node = nodeInfo.getNode();
        List<Node> resourceNodeList = ownerPool.get(resourceId);
        //resourceNodeList 和ownerPool 都已经加锁,为何还需要synchronized 
        //为了提高程序效率
        if (resourceNodeList == null) {
            synchronized (resourceNodeInfoLock) {
                resourceNodeList = ownerPool.get(resourceId);
                if (resourceNodeList == null) {
                    resourceNodeList = Collections.synchronizedList(new ArrayList<>());
                    ownerPool.put(resourceId,  resourceNodeList);
                }
            }
        }
        resourceNodeList.add(node);
        nodeInfo.incCount();
    }

    //注销资源
     void removeResource(Node node, Integer resourceId) {
        ResourceNodeInfo nodeInfo = checkAddress(node);
        if (nodeInfo == null) {
            return;
        }
        //资源拥有者列表
        List<Node> resourceNodeList = ownerPool.get(resourceId);
        if (resourceNodeList == null) {
            return;
        }
        resourceNodeList.remove(nodeInfo.getNode());

        if (nodeInfo.deCount() <= 0) {
            nodePool.remove(nodeInfo.hashCode());
        }
    }


  
    //注销发送端
    void removeNode(Node node) {
        ResourceNodeInfo nodeInfo = checkAddress(node);
        if (nodeInfo == null) {
            return;
        }
        Set<Integer> resourceIdSet = ownerPool.keySet();
        for (Integer resourceId : resourceIdSet) {
            List<Node> nodes = ownerPool.get(resourceId);
            nodes.remove(node);
        }
        nodePool.remove(nodeInfo.hashCode());
    }
    //设置发送端健康值
    void setNodeHealth(Node node, int health) {
        ResourceNodeInfo nodeInfo = checkAddress(node);
        if (nodeInfo == null) {
            return;
        }

        nodeInfo.setHealth(health);
    }
    //获取地址列表
    List<Node> getNodeList(int resourceId) {
        return ownerPool.get(resourceId);
    }
}

资源拥有者池是基于多线程的。其中Map<Integer, List> ownerPool、Map<Integer, ResourceNodeInfo> nodePool; 读写存在线程安全。List、ResourceNodeInfo生成 都需要加DCL。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值