forked from KNEMC/KLALB
102 lines
2.7 KiB
Java
102 lines
2.7 KiB
Java
package org.kne.cloud.network;
|
|
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
import java.util.concurrent.locks.LockSupport;
|
|
import java.util.function.LongUnaryOperator;
|
|
import java.util.function.UnaryOperator;
|
|
|
|
public class SpeedLimiter {
|
|
|
|
public boolean isHitlimit() {
|
|
return hitlimit;
|
|
}
|
|
private volatile long limitspeed=1024*1024;
|
|
private long brustTime=2000000L;
|
|
private volatile boolean hitlimit=false;
|
|
public long getLimitspeed() {
|
|
return limitspeed;
|
|
}
|
|
|
|
public SpeedLimiter(long limitspeed) {
|
|
super();
|
|
this.limitspeed = limitspeed;
|
|
}
|
|
public SpeedLimiter(long limitspeed, long brustTime) {
|
|
super();
|
|
this.limitspeed = limitspeed;
|
|
this.brustTime = brustTime;
|
|
}
|
|
|
|
public void setLimitspeed(long limitspeed) {
|
|
this.limitspeed = limitspeed;
|
|
//System.out.println("更新限速:"+limitspeed);
|
|
}
|
|
|
|
public long getBrustTime() {
|
|
return brustTime;
|
|
}
|
|
|
|
public void setBrustTime(long brustTime) {
|
|
this.brustTime = brustTime;
|
|
}
|
|
private AtomicLong ltime=new AtomicLong( System.nanoTime());
|
|
private AtomicLong waitingtime=new AtomicLong();
|
|
@Override
|
|
public String toString() {
|
|
return "SpeedLimiter [limitspeed=" + limitspeed + ", brustTime=" + brustTime + ", hitlimit=" + hitlimit
|
|
+ ", ltime=" + ltime + ", waitingtime=" + waitingtime + "]";
|
|
}
|
|
public void forceTransmit(long datasize) {
|
|
long limitspeedx=limitspeed;
|
|
if(limitspeedx>0) {
|
|
long curtime=System.nanoTime();
|
|
long pasttime=ltime.getAndSet(curtime);
|
|
long nv=waitingtime.updateAndGet(new LongUnaryOperator() {
|
|
@Override
|
|
public long applyAsLong(long t) {
|
|
t-=curtime-pasttime;
|
|
if(t<0L)
|
|
t=0L;
|
|
return t;
|
|
}
|
|
|
|
});
|
|
waitingtime.addAndGet((long) (datasize*1000000000.0/limitspeedx));
|
|
}
|
|
}
|
|
//用系统计时器的时刻相减得到经过的时间,与数据包除以限速值得到的应消耗的时间做对比,若时间还未到达发送下一个数据包的时机,则返回false
|
|
public boolean checkTransmit(long datasize) {
|
|
long limitspeedx=limitspeed;
|
|
if(limitspeedx<=0) {
|
|
return false;
|
|
}
|
|
|
|
long curtime=System.nanoTime();
|
|
long pasttime=ltime.getAndSet(curtime);
|
|
long nv=waitingtime.updateAndGet(new LongUnaryOperator() {
|
|
@Override
|
|
public long applyAsLong(long t) {
|
|
t-=curtime-pasttime;
|
|
if(t<0L)
|
|
t=0L;
|
|
return t;
|
|
}
|
|
|
|
});
|
|
if(nv<=brustTime) {
|
|
return true;
|
|
}else {
|
|
return false;
|
|
}
|
|
}
|
|
public void transmit(long datasize) {
|
|
long limitspeedx=limitspeed;
|
|
while(!checkTransmit(datasize)) {
|
|
//LockSupport.parkNanos(100000);
|
|
Thread.yield();
|
|
}
|
|
waitingtime.addAndGet((long) (datasize*1000000000.0/limitspeedx));
|
|
}
|
|
|
|
}
|