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() { // TODO: Record the chunk start time in chunkStatus. chunkStatus.setStartTimeMs(System.currentTimeMillis()); double downloaded = 0.0; System.out.printf("[%s] Started — Chunk #%d (%.1f MB)%n", Thread.currentThread().getName(), chunkStatus.getChunkId(), chunkStatus.getChunkSizeMB()); // TODO: Print a message that this chunk has started downloading. while (downloaded < chunkStatus.getChunkSizeMB()) { int delay = config.getMinStepDelayMs() + random.nextInt(config.getMaxStepDelayMs() - config.getMinStepDelayMs() + 1); // TODO: Generate a random sleep delay between min and max delay. // TODO: Sleep for that delay. // TODO: Generate a random download amount for this step. // TODO: Increase downloaded, but do not go beyond chunk size. // TODO: Save the updated downloaded value into chunkStatus. // TODO: Optionally print step-by-step progress. try { Thread.sleep(delay); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } double step = config.getMinStepDownloadMB() + random.nextDouble() * (config.getMaxStepDownloadMB() - config.getMinStepDownloadMB()); downloaded = Math.min(downloaded + step, chunkStatus.getChunkSizeMB()); chunkStatus.setDownloadedMB(downloaded); System.out.printf("[%s] Chunk #%d → %.2f / %.1f MB (%.1f%%)%n", Thread.currentThread().getName(), chunkStatus.getChunkId(), chunkStatus.getDownloadedMB(), chunkStatus.getChunkSizeMB(), chunkStatus.getProgressPercentage()); } // TODO: Mark the chunk as completed. // TODO: Record the chunk end time in chunkStatus. // TODO: Print a message that this chunk has finished downloading. chunkStatus.setCompleted(true); chunkStatus.setEndTimeMs(System.currentTimeMillis()); System.out.printf("[%s] Finished — Chunk #%d in %d ms%n", Thread.currentThread().getName(), chunkStatus.getChunkId(), chunkStatus.getDownloadDurationMs()); } }