我试图编写一个支持设置tps值的线程库。不过,我有一个问题,就是当租者置其屋计划是15个时,平均时间是66,667毫秒。由于线程只能在完整毫秒内休眠,所以我的解决方案是创建一个查找表,其中所有值加起来都可达1000 ms。
因此,如果我希望每秒钟有15次滴答,我只需在0到14之间做一个for循环,并在表中查找最大睡眠时间。我的问题是如何计算查找表中的值?
我的方法是这样的:
int tps = 15;
int[] sleepTime = new int[tps];
float tickTime = 1000.0f / tps;
float increment = 1.0f - (tickTime - (int) tickTime);
float overflow = 0;
int c = 0;
for (int n = 0; n < tps; n++) {
if (overflow >= 1) overflow = 0;
sleepTime[n] = (int) tickTime + (int) Math.ceil(overflow);
c += sleepTime[n];
overflow += increment;
}
System.out.println(Arrays.toString(sleepTime));
System.out.println("Complete sleep time: " + c);
这对于像15这样的小值很好,但是当我想拥有更高的值(比如31 tps )时,所有计算值的总和都在1000以上(1007对于31)。
发布于 2019-03-03 07:47:29
您可以一步一步地从剩余睡眠时间减去整数除法的值:
int[] tps(int tps) {
int[] sleepTimes = new int[tps];
for (int i = 0, remainder = 1000; i < tps; i++) {
int sleepTime = remainder / (tps - i);
sleepTimes[i] = sleepTime;
remainder -= sleepTime;
}
return sleepTimes;
}
tps(3)
的实例评价
要使受影响的值和上限值分布均匀,可以执行以下操作:
int[] tps(int tps) {
int[] sleepTimes = new int[tps];
int low = 1000 / tps; // the floored value
Arrays.fill(sleepTimes, low);
int mod = 1000 % tps; // number of ceiled values to insert
if (mod > 0) {
int high = low + 1; // the ceiled value
float rate = tps / (float) mod; // the insertion rate
for (int i = 0; i < mod; i++) {
sleepTimes[Math.round(i * rate)] = high;
}
}
return sleepTimes;
}
tps(21)
:48,47,48,48,47,48,E 122
48,47,<>E 12448e 225,47,<>E 12648E 227
,<>E 12848E 229
47,E 130
48E 231>代码> 47,<代码>E 132
48EE>E 134<48代码><48代码E 235>代码> 47 >代码>E>E><136<代码<>代码><><>代码><>
发布于 2019-03-03 11:36:52
Thread.sleep(long millis, int nanos)
休眠毫秒和纳秒。所以,计算准确的睡眠时间,然后解雇一个工作人员(在另一个线程中)并重新睡眠。这意味着工人的执行时间并不重要。
为了避免漂移错误,根据开始时间和计数器进行睡眠计算。每一个知道,然后线程将睡得少一点,以补偿它自己处理睡眠计时器所需的少量时间。
https://stackoverflow.com/questions/54969953
复制相似问题