class AbstractLoadBalance<T> implements LoadBalance<T> {
    public static final int MAX_REFERER_COUNT = 10;

    protected URL clusterUrl;
    private List<Referer<T>> referers;

    @Override
    public void init(URL clusterUrl) {
        this.clusterUrl = clusterUrl;
    }

    @Override
    public void onRefresh(List<Referer<T>> referers) {
        onRefresh(referers, true);
    }

    protected void onRefresh(List<Referer<T>> referers, boolean shuffle) {
        if (shuffle) {
            Collections.shuffle(referers);
        }
        // replaced only
        this.referers = referers;
    }

    @Override
    public Referer<T> select(Request request) {
        List<Referer<T>> referers = this.referers;
        if (referers == null) {
            throw new MotanServiceException(this.getClass().getSimpleName() + " No available referers for call request:" + request);
        }
        Referer<T> ref = null;
        if (referers.size() > 1) {
            ref = doSelect(request);

        } else if (referers.size() == 1) {
            ref = referers.get(0).isAvailable() ? referers.get(0) : null;
        }

        if (ref != null) {
            return ref;
        }
        throw new MotanServiceException(this.getClass().getSimpleName() + " No available referers for call request:" + request);
    }

    @Override
    public void selectToHolder(Request request, List<Referer<T>> refersHolder) {
        List<Referer<T>> referers = this.referers;

        if (referers == null) {
            throw new MotanServiceException(this.getClass().getSimpleName() + " No available referers for call : referers_size= 0 "
                    + MotanFrameworkUtil.toString(request));
        }

        if (referers.size() > 1) {
            doSelectToHolder(request, refersHolder);

        } else if (referers.size() == 1 && referers.get(0).isAvailable()) {
            refersHolder.add(referers.get(0));
        }
        if (refersHolder.isEmpty()) {
            throw new MotanServiceException(this.getClass().getSimpleName() + " No available referers for call : referers_size="
                    + referers.size() + " " + MotanFrameworkUtil.toString(request));
        }
    }

    protected List<Referer<T>> getReferers() {
        return referers;
    }

    protected Referer<T> selectFromRandomStart(List<Referer<T>> referers) {<FILL_FUNCTION_BODY>}

    protected void addToSelectHolderFromStart(List<Referer<T>> referers, List<Referer<T>> refersHolder, int start) {
        for (int i = 0, count = 0; i < referers.size() && count < MAX_REFERER_COUNT; i++) {
            Referer<T> referer = referers.get((i + start) % referers.size());
            if (referer.isAvailable()) {
                refersHolder.add(referer);
                count++;
            }
        }
    }


    @Override
    public void setWeightString(String weightString) {
        LoggerUtil.info("ignore weightString:" + weightString);
    }

    protected abstract Referer<T> doSelect(Request request);

    protected abstract void doSelectToHolder(Request request, List<Referer<T>> refersHolder);
}

        int index = ThreadLocalRandom.current().nextInt(referers.size());
        Referer<T> ref;
        for (int i = 0; i < referers.size(); i++) {
            ref = referers.get((i + index) % referers.size());
            if (ref.isAvailable()) {
                return ref;
            }
        }
        return null;
    
<no_super_class>