0

我在如何实现一些时间的概念上有点挣扎。

基本上,我需要编写一些代码来有效地执行加速以向服务器发出请求。

为了进一步解释,我需要在 15 分钟的启动期间向服务器发出请求。15 分钟后,应以每秒 3 个请求的速率发出。在加速期开始时,我们可以从(比如说)每 3 秒 1 个请求开始。它如何达到每秒 3 个请求的速率并不重要,但它应该在 15 分钟之前达到这个速率。

我需要帮助的是将其实现为计时器。我需要一个函数来返回在发送下一个请求之前等待的时间。

所以我有一个这样的循环:

  • 发送请求
  • 等待 x 时间(其中 x 由函数返回)

这种情况一直持续到 15 分钟,因此该函数始终返回 0.3 秒的值(实现每秒 3 个请求 - 假设请求需要 0 秒发送,但这没关系......)

提供的值是: - 总加速时间。- 加速时间结束时每秒的请求数。- 加速时间开始时的每秒请求数。

任何帮助,将不胜感激。

4

3 回答 3

3

由于您不太关心速率加速的确切方式,您可以选择以下假设:

  1. 速率将随时间线性增加
  2. 只要我们不放慢速度,可以对速率进行一些近似和四舍五入

您从 time=0 开始,到 time=15

在 time=0 时,您的速率是(例如)每 3 秒 1 次。在 time=15 时,您的速率是每 0.3333 秒 1 从 0 到 15 的总变化是 (3 - 0.3333=) 2.77777

将此除以 15,得到 0.1777777。这意味着:如果您的汇率每秒下降 0.177777,您可以从 3 开始,最终在 0.3333

这显示在这样的线性图上:

在此处输入图像描述

因此,如果您有一种方法可以知道自开始 (x) 以来经过了多长时间(以秒为单位),您就可以计算出当前的速率应该是多少。

double computeRate(double secondsSinceStart)
{
   return 3 * (-0.177777 *  Math.floor(secondsSinceStart));
}

该计算是您必须等待的秒数。

使用类似的原理,您可以假设一条非线性曲线,或以其他方式对其进行调整。

于 2013-09-16T13:42:27.080 回答
1
/**
 * start is the moment the first request is sent (in ms)
 * end is the moment, in which the targetDelta should be reached (in ms)
 * targetDelta is the targeted period between two requests (0.3)
 * initDelta is the initial delta (1.0)
 */
private int getWaitingPeriod(long start, long end, double targetDelta, double initDelta) {
    double timePassed = (double) (System.currentTimeMillis() - start);
    double progress = timePassed / (double) (end - start);
    if(progress >= 1) return (int) (targetDelta * 1000);
    return (int) ((targetDelta - (targetDelta - initDelta) * progress) * 1000);
}

未经测试,但这是您要搜索的内容吗?

编辑:哎呀,忘记将秒转换为毫秒。现在测试,例如:

    long start = System.currentTimeMillis();
    while(System.currentTimeMillis() < start + 10000) { //testing with 10 seconds

        int wait = getWaitingPeriod(start, start + 10000, 1, 0.3);
        System.out.println("waiting " + wait + "ms");
        try {
            Thread.sleep(wait);
        } catch(InterruptedException ex) {}

    }
于 2013-09-16T13:32:58.900 回答
0

您可以首先创建一个处理发送请求的类(如果还没有的话)。类似的东西(这更面向对象):

public class RequestSender {

double startTime;

    // ramp up time is in minutes
double rampUpTime;
boolean firstRequest;
int requestPerSecBeforeTime;
int requestPerSecAfterTime;

RequestSender(double rampUpTime, int requestPerSecBeforeTime, int requestPerSecAfterTime){
    this.rampUpTime = rampUpTime;
    this.requestPerSecAfterTime = requestPerSecAfterTime;
    this.requestPerSecBeforeTime = requestPerSecAfterTime;
    firstRequest=true;
}

public void sendRequest(){
    if (firstRequest){
        startTime = System.currentTimeMillis();
        firstRequest = false;
    }
    // do stuff to send requests
}

public double getWaitTime(){
    if ((System.currentTimeMillis() - startTime)/60000 > rampUpTime){
        return 1/requestPerSecAfterTime;
    }
    else {
        return 1/requestPerSecBeforeTime;
    }
}

}

然后你可以在你的代码中使用这个对象:

 RequestSender rs = new RequestSender(15, 1, 3);
 rs.sendRequest();
 Thread.wait(rs.getWaitTime());
于 2013-09-16T13:40:47.913 回答