定义接口
public interface RoundRobin<T> { T nextData(); }
实现
算法来自nginx
public class WeightedRoundRobin<T> implements RoundRobin<T> { private List<Item<T>> items = new ArrayList<>(); public WeightedRoundRobin(Map<T, Integer> datas) { List<Item<T>> initItems = datas.entrySet() .stream() .map(e -> new Item<>(e.getKey(), e.getValue())) .collect(Collectors.toList()); items.addAll(initItems); } public T nextData() { Item<T> bestItem = null; int total = 0; for (Item<T> currentItem : items) { currentItem.currentWeight += currentItem.effectiveWeight; total += currentItem.effectiveWeight; if (currentItem.effectiveWeight < currentItem.weight) { currentItem.effectiveWeight++; } if (bestItem == null || currentItem.currentWeight > bestItem.currentWeight) { bestItem = currentItem; } } if (bestItem == null) { return null; } bestItem.currentWeight -= total; return bestItem.getData(); } public List<Item<T>> getItems() { return items; } public void setItems(List<Item<T>> items) { this.items = items; } public static final class Item<T> { private T data; private int weight; private int effectiveWeight; private int currentWeight; public Item(T data, int weight) { this.data = data; this.weight = weight; } public T getData() { return data; } public void setData(T data) { this.data = data; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } public int getEffectiveWeight() { return effectiveWeight; } public void setEffectiveWeight(int effectiveWeight) { this.effectiveWeight = effectiveWeight; } public int getCurrentWeight() { return currentWeight; } public void setCurrentWeight(int currentWeight) { this.currentWeight = currentWeight; } @Override public String toString() { return Item{ + data= + data + , weight= + weight + , effectiveWeight= + effectiveWeight + , currentWeight= + currentWeight + '}'; } } }
使用
Map<Integer, Integer> testDatas = new HashMap<Integer, Integer>() {{ put(1, 3); // 权重3 put(2, 5); // 权重5 put(3, 8); // 权重8 }}; WeightedRoundRobin<Integer> roundRobin = new WeightedRoundRobin<>(testDatas); for (int i = 0; i < 20; i++) { LOGGER.info(id: {}, roundRobin.nextData()); }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。