java同步机制

发布于 2024-11-01 15:39:21 字数 156 浏览 0 评论 0原文

Web 应用程序查询外部服务器。如果过去“n”分钟内发送到服务器的请求中有超过 80% 失败,则 Web 应用程序应退出查询服务器并执行其他逻辑。我可以想到一个原子整数会因失败的请求而增加。但我不认为原子整数支持在原子整数的值达到特定值时执行的任何操作。在java中有没有更聪明的方法来做到这一点?

A web application queries an external server. If more than 80% of the requests to the server send within the past 'n' minutes fails, then the web applicatoin should back out from querying the server and perform other logic. I could think of an atomic integer being incremented by the failed requests. But i dont think atomic integer supports any action to be executed if the value of the atomic integer reaches a particular value. Is there any smarter way to do this in java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心在旅行 2024-11-08 15:39:21

好吧,更新原子整数后,您可以检查它的值,如果满足 80%,那么您可以采取行动(例如将该服务器标记为“弱响应等”)。如果您在多线程环境中工作,那么您的解决方案没有任何问题。

另一种解决方案是让线程调用同步方法来增加非原子整数并执行检查。该整数必须是该方法所属类的属性。

Well, after updating your atomic integer, you could check its value and if the 80% is met, then you could take action (like flagging that server as 'weak responding or so'). If you are working in a multi-threaded environment, there is nothing wrong with your solution.

Another solution is to have the threads call a synchronized method to increase a non-atomic integer and perform the check. That integer would have to be an attribute of the class to which this method belongs.

债姬 2024-11-08 15:39:21

如果您想监视最后“N”分钟内的事件,您需要的不仅仅是一个整数。您需要知道“N”分钟前发生了什么,这样您才能保持正确的成功水平估计。

这是一种方法:

import java.util.LinkedList;

/**
 * Class that monitors outcomes for until the proportion of successes in a
 * specified time window falls below a trigger level, at which point an action
 * is invoked.
 * 
 * @author Simon
 */
public class SuccessMonitor {
    /** An outcome */
    static class Outcome {
        /** Time of outcome */
        final long eventTime = System.currentTimeMillis();

        /** True for success, false for failure */
        boolean outcome;
    }

    /** The action to invoke when there are two few successes */
    private final Runnable action_;

    /** The history of outcomes in the time window */
    private final LinkedList<Outcome> events_ = new LinkedList<Outcome>();

    /** Number of successes in the time window */
    private int goodCount_ = 0;

    /** Synchronization lock */
    private final Object lock_ = new Object();

    /** Length of the time window in milliseconds */
    private final long trackTime_;

    /** The success proportion at which to invoke the action */
    private final double triggerLevel_;


    /**
     * New monitor
     * 
     * @param trackTime
     *            number of milliseconds to retain history for
     * @param triggerLevel
     *            the level at which to invoke the action
     * @param action
     *            the action
     */
    public SuccessMonitor(long trackTime, double triggerLevel, Runnable action) {
        trackTime_ = trackTime;
        triggerLevel_ = triggerLevel;
        action_ = action;
    }


    private void check(boolean result) {
        // create a new outcome
        Outcome out = new Outcome();
        out.outcome = result;

        double level;
        synchronized (lock_) {
            // add the new outcome
            goodCount_ += (result) ? 1 : 0;
            events_.addLast(out);

            // remove expired outcomes
            long expire = System.currentTimeMillis() - trackTime_;
            while( (!events_.isEmpty())
                    && (events_.getFirst().eventTime < expire) ) {
                out = events_.removeFirst();
                goodCount_ -= (out.outcome) ? 1 : 0;
            }

            // Calculate the success level.
            if (events_.isEmpty()) {
                // if empty assume ok
                level = 1.0;
            } else {
                // calculate success level
                level = (double) goodCount_ / events_.size();
            }
        }

        // if level has fallen too low, invoke action
        if (level < triggerLevel_) action_.run();
    }


    /**
     * Notify this monitor of a failure.
     */
    public void fail() {
        check(false);
    }


    /**
     * Reset this monitor, causing it to discard all currently stored history.
     */
    public void reset() {
        synchronized (lock_) {
            events_.clear();
            goodCount_ = 0;
        }
    }


    /**
     * Notify this monitor of a success.
     */
    public void success() {
        check(true);
    }
}

If you want to monitor events in the last 'N' minutes you need more than just an integer. You need to know what was happening 'N' minutes ago so you can keep your success level estimate correct.

Here is one way to do it:

import java.util.LinkedList;

/**
 * Class that monitors outcomes for until the proportion of successes in a
 * specified time window falls below a trigger level, at which point an action
 * is invoked.
 * 
 * @author Simon
 */
public class SuccessMonitor {
    /** An outcome */
    static class Outcome {
        /** Time of outcome */
        final long eventTime = System.currentTimeMillis();

        /** True for success, false for failure */
        boolean outcome;
    }

    /** The action to invoke when there are two few successes */
    private final Runnable action_;

    /** The history of outcomes in the time window */
    private final LinkedList<Outcome> events_ = new LinkedList<Outcome>();

    /** Number of successes in the time window */
    private int goodCount_ = 0;

    /** Synchronization lock */
    private final Object lock_ = new Object();

    /** Length of the time window in milliseconds */
    private final long trackTime_;

    /** The success proportion at which to invoke the action */
    private final double triggerLevel_;


    /**
     * New monitor
     * 
     * @param trackTime
     *            number of milliseconds to retain history for
     * @param triggerLevel
     *            the level at which to invoke the action
     * @param action
     *            the action
     */
    public SuccessMonitor(long trackTime, double triggerLevel, Runnable action) {
        trackTime_ = trackTime;
        triggerLevel_ = triggerLevel;
        action_ = action;
    }


    private void check(boolean result) {
        // create a new outcome
        Outcome out = new Outcome();
        out.outcome = result;

        double level;
        synchronized (lock_) {
            // add the new outcome
            goodCount_ += (result) ? 1 : 0;
            events_.addLast(out);

            // remove expired outcomes
            long expire = System.currentTimeMillis() - trackTime_;
            while( (!events_.isEmpty())
                    && (events_.getFirst().eventTime < expire) ) {
                out = events_.removeFirst();
                goodCount_ -= (out.outcome) ? 1 : 0;
            }

            // Calculate the success level.
            if (events_.isEmpty()) {
                // if empty assume ok
                level = 1.0;
            } else {
                // calculate success level
                level = (double) goodCount_ / events_.size();
            }
        }

        // if level has fallen too low, invoke action
        if (level < triggerLevel_) action_.run();
    }


    /**
     * Notify this monitor of a failure.
     */
    public void fail() {
        check(false);
    }


    /**
     * Reset this monitor, causing it to discard all currently stored history.
     */
    public void reset() {
        synchronized (lock_) {
            events_.clear();
            goodCount_ = 0;
        }
    }


    /**
     * Notify this monitor of a success.
     */
    public void success() {
        check(true);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文