parent
d1e591b448
commit
5bdc1c881b
@ -0,0 +1,104 @@ |
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one |
||||
* or more contributor license agreements. See the NOTICE file |
||||
* distributed with this work for additional information |
||||
* regarding copyright ownership. The ASF licenses this file |
||||
* to you under the Apache License, Version 2.0 (the |
||||
* "License"); you may not use this file except in compliance |
||||
* with the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.common; |
||||
|
||||
/** |
||||
* 速度限制 |
||||
*/ |
||||
public class BandwidthLimiter { |
||||
public static int maxBandWith = 2 * 1024; //KB
|
||||
|
||||
/* KB */ |
||||
private static Long KB = 1024L; |
||||
/* The smallest count chunk length in bytes */ |
||||
private static Long CHUNK_LENGTH = 1024L; |
||||
/* How many bytes will be sent or receive */ |
||||
private int bytesWillBeSentOrReceive = 0; |
||||
/* When the last piece was sent or receive */ |
||||
private long lastPieceSentOrReceiveTick = System.nanoTime(); |
||||
/* Default rate is 1024KB/s */ |
||||
private int maxRate = 1024; |
||||
/* Time cost for sending CHUNK_LENGTH bytes in nanoseconds */ |
||||
private long timeCostPerChunk = (1000000000L * CHUNK_LENGTH) |
||||
/ (this.maxRate * KB); |
||||
|
||||
/** |
||||
* Initialize a BandwidthLimiter object with a certain rate. |
||||
* |
||||
* @param maxRate the download or upload speed in KBytes |
||||
*/ |
||||
public BandwidthLimiter(int maxRate, int threadNum) { |
||||
if (threadNum > 1) { |
||||
maxRate = maxRate / threadNum; |
||||
} |
||||
this.setMaxRate(maxRate); |
||||
} |
||||
|
||||
/** |
||||
* Set the max upload or download rate in KB/s. maxRate must be grater than |
||||
* 0. If maxRate is zero, it means there is no bandwidth limit. |
||||
* |
||||
* @param maxRate If maxRate is zero, it means there is no bandwidth limit. |
||||
* @throws IllegalArgumentException |
||||
*/ |
||||
public synchronized void setMaxRate(int maxRate) |
||||
throws IllegalArgumentException { |
||||
if (maxRate < 0) { |
||||
throw new IllegalArgumentException("maxRate can not less than 0"); |
||||
} |
||||
this.maxRate = maxRate; |
||||
if (maxRate == 0) { |
||||
this.timeCostPerChunk = 0; |
||||
} else { |
||||
this.timeCostPerChunk = (1000000000L * CHUNK_LENGTH) |
||||
/ (this.maxRate * KB); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Next 1 byte should do bandwidth limit. |
||||
*/ |
||||
public synchronized void limitNextBytes() { |
||||
this.limitNextBytes(1); |
||||
} |
||||
|
||||
/** |
||||
* Next len bytes should do bandwidth limit |
||||
*/ |
||||
public synchronized void limitNextBytes(int len) { |
||||
this.bytesWillBeSentOrReceive += len; |
||||
|
||||
/* We have sent CHUNK_LENGTH bytes */ |
||||
while (this.bytesWillBeSentOrReceive > CHUNK_LENGTH) { |
||||
long nowTick = System.nanoTime(); |
||||
long missedTime = this.timeCostPerChunk |
||||
- (nowTick - this.lastPieceSentOrReceiveTick); |
||||
if (missedTime > 0) { |
||||
try { |
||||
Thread.currentThread().sleep(missedTime / 1000000, |
||||
(int) (missedTime % 1000000)); |
||||
} catch (InterruptedException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
this.bytesWillBeSentOrReceive -= CHUNK_LENGTH; |
||||
this.lastPieceSentOrReceiveTick = nowTick |
||||
+ (missedTime > 0 ? missedTime : 0); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue