import java.util.Random; public class DownloadWorker implements Runnable { private final ChunkStatus chunkStatus; private final DownloadConfig config; private final Random random; public DownloadWorker(ChunkStatus chunkStatus, DownloadConfig config) { this.chunkStatus = chunkStatus; this.config = config; this.random = new Random(); } @Override public void run() { chunkStatus.setStartTimeMs(System.currentTimeMillis()); System.out.println(Thread.currentThread().getName() + " started downloading."); double downloaded = 0.0; double chunkSize = chunkStatus.getChunkSizeMB(); while (downloaded < chunkSize) { int delayMs = config.getMinStepDelayMs() + random.nextInt(config.getMaxStepDelayMs() - config.getMinStepDelayMs() + 1); try { Thread.sleep(delayMs); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() + " was interrupted."); return; } double stepDownload = config.getMinStepDownloadMB() + (config.getMaxStepDownloadMB() - config.getMinStepDownloadMB()) * random.nextDouble(); downloaded += stepDownload; if (downloaded > chunkSize) { downloaded = chunkSize; } chunkStatus.setDownloadedMB(downloaded); } chunkStatus.setCompleted(true); chunkStatus.setEndTimeMs(System.currentTimeMillis()); System.out.println(Thread.currentThread().getName() + " finished downloading."); } }