I'm trying to limit download speed in a multithreaded downloader application (like IDM). I've done this so far with the help of this answer, but it doesn't work and I have no idea why. Here is my wrapper class:
public class DownloadStream
{
InputStream in;
long timestamp;
static int counter = 0;
static int INTERVAL = 1000;
static int LIMIT;
static boolean speedLimited;
public DownloadStream(InputStream stream, boolean speedLimited, int kbytesPerSecond)
{
LIMIT = kbytesPerSecond * 1000;
this.speedLimited = speedLimited;
in = stream;
}
public int read(byte[] buffer) throws IOException
{
if(!speedLimited)
return in.read(buffer);
check();
int res = in.read(buffer);
if (res >= 0) {
counter += res;
}
return res;
}
public synchronized void check()
{
if (counter > LIMIT)
{
long now = System.currentTimeMillis();
if (timestamp + INTERVAL >= now) {
try
{
Thread.sleep(timestamp + INTERVAL - now);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
timestamp = now;
counter -= LIMIT;
}
}
}
I use it like an InputStream
in each of my downloader threads:
byte[] buffer = new byte[4096];
while((length = input.read(buffer)) != -1)
{
output.write(buffer,0,length);
}
Download speed goes up to 16 kilobytes per second if I enter 1 as kbytesPerSecond
with eight threads. I've made counter
static to prevent from this, but it doesn't work.