最近在看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();
}
}
}