gassip协议极简java版实现

最近在看gassip协议,为了加深理解,自己写了一个简单的测试程序。

流程大致如下:

结构:环形结构,每个节点都知道全局总共有几个节点

从0节点开始,寻找N个未接收到流言的节点进行传播(n=每次要传播的数据)

import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;

public class GassipTest {

    public final static List<Node> nodeList = new ArrayList<>();
    public final static int BASE = 2; //每次传播的人数
    public static int recvCount = 0;
    public static int successRecvCount = 0;
    public static int sendCount = 0;


    public static void main(String[] args) throws InterruptedException {
        ReentrantLock lock = new ReentrantLock();
        for (int i=0;i<6;i++){
            Node node = new Node(i,BASE,lock);
            nodeList.add(node);
        }

        nodeList.stream().forEach(e -> e.start());

        Thread.sleep(3000L);
        System.out.println("传播总计:"+sendCount);
        System.out.println("收到node总计:"+recvCount);
        System.out.println("收到成功node总计:"+successRecvCount);

    }


    @Data
    static class Node extends Thread{

        Node(int num,int base,ReentrantLock lock){
            this.num = num;
            this.base = base;
            this.lock = lock;

        }
        private int num;
        private int base; //每次传播次数
        private Random random = new Random();
        private boolean hasRevGasship = false;
        private ReentrantLock lock;

        /**
         * 每次随机取base个节点发送数据(排除自己)
         */
        public boolean sendGassip(){
            try{
                lock.lock();
                sendCount++;
                int count = 0;
                while(count < base){
                    toOther();
                    count++;
                }
                return true;
            } finally {
                lock.unlock();
            }

        }

        //从能接触到的人里面找到base个没收到流言的人发送流言,如果都收到了,返回false
        private boolean toOther(){
            int idx = 0;
            int sendCount = 0;
            while(idx<nodeList.size() && sendCount < base){
                //发送不成功
                if(!nodeList.get(idx).recvGassip()){
                    idx++;
                } else {
                    sendCount++;
                }
            }
            return idx<nodeList.size() ? true: false;
        }


        public boolean recvGassip(){
            try{
                lock.lock();
                recvCount++;
//                System.out.println(num+":recvGassip");
                if(!hasRevGasship){//没有接到过流言
                    successRecvCount++;
                    hasRevGasship = true;
                    System.out.println("node<"+num+">:recvGasship.");
                    sendGassip();
                    return true;
                }
                return false;
            } finally {
                lock.unlock();
            }

        }

        @Override
        public void run() {
                sendGassip();
        }
    }

}


相关推荐

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

阿拉希神猪

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值