import java.util.Random; /** * Simulates downloading a single chunk of a file. * *

This class is intentionally provided as a skeleton for students. * The main multithreading and simulation logic should be completed * in the run() method.

*/ 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() { long startTime = System.currentTimeMillis(); chunkStatus.setStartTime(startTime); double downloaded = 0.0; System.out.println("Chunk \"" + chunkStatus.getChunkId() + "\" started downloading."); while (downloaded < chunkStatus.getChunkSizeMB()) { try { //Generate a random sleep delay between min and max delay. int minDelay = config.getMinDelayMs(); int maxDelay = config.getMaxDelayMs(); int randomDelay = random.nextInt((maxDelay - minDelay) + 1) + minDelay; //Sleep for that delay. Thread.sleep(randomDelay); //Generate a random download amount for this step. double minStep = config.getMinStepDelayMs(); double maxStep = config.getMaxStepDelayMs(); double randomStep = (maxStep + minStep)*random.nextDouble() + minStep; //Increase downloaded, but do not go beyond chunk size. downloaded += randomStep; if (downloaded > chunkStatus.getChunkSizeMB()) { downloaded = chunkStatus.getChunkSizeMB(); } //Save the updated downloaded value into chunkStatus. chunkStatus.setDownloadedMB(downloaded); //print step-by-step progress. System.out.printf("Chunk #%d: Downloaded %.2f / %.2f MB%n", chunkStatus.getChunkId(), downloaded, chunkStatus.getChunkSizeMB()); } catch (InterruptedException e) { System.out.println("Chunk \"" + chunkStatus.getChunkId() + "\" was interrupted!"); return; } } //Mark the chunk as completed. chunkStatus.setCompleted(true); //Record the chunk end time in chunkStatus. long endTime = System.currentTimeMillis(); chunkStatus.setEndTimeMs(endTime); //Print a message that this chunk has finished downloading. System.out.println("Chunk \"" + chunkStatus.getChunkId() + "\" has finished downloading."); } }