diff --git a/src/main/java/DownloadWorker.java b/src/main/java/DownloadWorker.java
index 546de2d..8ebf0d9 100644
--- a/src/main/java/DownloadWorker.java
+++ b/src/main/java/DownloadWorker.java
@@ -1,12 +1,5 @@
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;
@@ -21,23 +14,43 @@ public class DownloadWorker implements Runnable {
@Override
public void run() {
- // TODO: Record the chunk start time in chunkStatus.
- double downloaded = 0.0;
+ chunkStatus.setStartTimeMs(System.currentTimeMillis());
- // TODO: Print a message that this chunk has started downloading.
+ double downloaded = 0;
+
+ System.out.println("Chunk " + chunkStatus.getChunkId() + " started.");
while (downloaded < chunkStatus.getChunkSizeMB()) {
- // 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.
+
+ int delay = random.nextInt(
+ config.getMaxStepDelayMs() - config.getMinStepDelayMs() + 1
+ ) + config.getMinStepDelayMs();
+
+ try {
+ Thread.sleep(delay);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ double amount = random.nextDouble() *
+ (config.getMaxStepDownloadMB() - config.getMinStepDownloadMB())
+ + config.getMinStepDownloadMB();
+
+ downloaded = downloaded + amount;
+
+ if (downloaded > chunkStatus.getChunkSizeMB()) {
+ downloaded = chunkStatus.getChunkSizeMB();
+ }
+
+ chunkStatus.setDownloadedMB(downloaded);
+
+ System.out.println("Chunk " + chunkStatus.getChunkId()
+ + ": " + downloaded + "/" + chunkStatus.getChunkSizeMB() + " MB");
}
- // 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.println("Chunk " + chunkStatus.getChunkId() + " finished.");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/Main.java b/src/main/java/Main.java
index 82bd239..e8fab42 100644
--- a/src/main/java/Main.java
+++ b/src/main/java/Main.java
@@ -5,8 +5,8 @@ public class Main {
public static void main(String[] args) {
System.out.println("=== Simulated Download Manager ===");
- // 1. Read config
DownloadConfig config;
+
try {
config = ConfigReader.readConfig("download_config.txt");
} catch (Exception e) {
@@ -19,13 +19,11 @@ public class Main {
System.out.println("Chunk count: " + config.getChunkCount());
System.out.println();
- // 2. Create chunks
List chunks = ChunkUtils.createChunks(
config.getTotalSizeMB(),
config.getChunkCount()
);
- // 3. Create worker threads
List workerThreads = new ArrayList<>();
for (ChunkStatus chunk : chunks) {
@@ -34,69 +32,49 @@ public class Main {
workerThreads.add(workerThread);
- // TODO:
- // Students may print helpful debug information here,
- // for example which chunk is assigned to which worker thread.
+ System.out.println("Chunk " + chunk.getChunkId()
+ + " assigned to " + workerThread.getName());
}
- // 4. Create and start monitor thread
ProgressMonitor monitor = new ProgressMonitor(config, chunks);
Thread monitorThread = new Thread(monitor, "Progress-Monitor");
- // TODO:
- // Start the monitor thread before starting the workers
- // so that progress can be displayed while downloading happens.
- //
- // Example idea:
- // monitorThread.start();
+ monitorThread.start();
- // 5. Start worker threads
- // TODO:
- // Start each worker thread in workerThreads.
- // Use a loop and call start() on each thread.
+ for (Thread thread : workerThreads) {
+ thread.start();
+ }
- // 6. Wait for workers to finish
- // TODO:
- // Wait for all worker threads to complete by calling join().
- // This should be done inside a try-catch block for InterruptedException.
- //
- // Hint:
- // for (Thread thread : workerThreads) {
- // thread.join();
- // }
+ for (Thread thread : workerThreads) {
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
- // TODO:
- // After all workers finish, the monitor thread may also need to stop.
- // Depending on how ProgressMonitor is implemented, students may:
- // - wait for it to finish on its own, or
- // - add a stopping mechanism in ProgressMonitor later.
- //
- // If your monitor finishes automatically, you may join it here.
+ try {
+ monitorThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
- // NOTE:
- // this final report may show 0 progress because no worker has actually run yet.
- // Until students complete the thread start/join TODOs above,
-
- // 7. Print final report
System.out.println();
System.out.println("=== Final Report ===");
int completedChunks = 0;
- double downloadedMB = 0.0;
+ double downloadedMB = 0;
for (ChunkStatus chunk : chunks) {
- downloadedMB += chunk.getDownloadedMB();
+ downloadedMB = downloadedMB + chunk.getDownloadedMB();
if (chunk.isCompleted()) {
completedChunks++;
}
- System.out.println(
- "Chunk " + chunk.getChunkId()
- + ": " + chunk.getDownloadedMB()
- + "/" + chunk.getChunkSizeMB()
- + " MB"
- );
+ System.out.println("Chunk " + chunk.getChunkId()
+ + ": " + chunk.getDownloadedMB()
+ + "/" + chunk.getChunkSizeMB() + " MB");
}
System.out.println();
@@ -104,4 +82,4 @@ public class Main {
System.out.println("Downloaded total: " + downloadedMB + "/" + config.getTotalSizeMB() + " MB");
System.out.println("Simulation finished.");
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/ProgressMonitor.java b/src/main/java/ProgressMonitor.java
index 475c0e0..456ae02 100644
--- a/src/main/java/ProgressMonitor.java
+++ b/src/main/java/ProgressMonitor.java
@@ -16,54 +16,40 @@ public class ProgressMonitor implements Runnable {
@Override
public void run() {
- // TODO:
- // Repeatedly check chunk progress until all chunks are completed.
- // In each loop:
- // 1. Read the downloaded size from every chunk
- // 2. Add all downloaded amounts to totalDownloadedMB
- // 3. Count completed chunks
- // 4. Print a progress message
- // 5. If completedChunks == chunks.size(), print a final monitor message and stop
- // 6. Otherwise sleep for monitorDelayMs and continue
-
while (true) {
- double totalDownloadedMB = 0.0;
+ double totalDownloadedMB = 0;
int completedChunks = 0;
for (ChunkStatus chunk : chunks) {
- totalDownloadedMB += chunk.getDownloadedMB();
+ totalDownloadedMB = totalDownloadedMB + chunk.getDownloadedMB();
if (chunk.isCompleted()) {
completedChunks++;
}
}
- double percent = 0.0;
+ double percent = 0;
+
if (totalSizeMB > 0) {
- percent = (totalDownloadedMB * 100.0) / totalSizeMB;
+ percent = (totalDownloadedMB * 100) / totalSizeMB;
}
- System.out.printf(
- "Progress for %s: %.1f/%.1f MB (%.2f%%), completed chunks: %d/%d%n",
- fileName,
- totalDownloadedMB,
- (double) totalSizeMB,
- percent,
- completedChunks,
- chunks.size()
- );
+ System.out.println("Progress for " + fileName + ": "
+ + totalDownloadedMB + "/" + totalSizeMB
+ + " MB (" + percent + "%), completed chunks: "
+ + completedChunks + "/" + chunks.size());
-
- // TODO:
- // If all chunks are completed, print a final message and exit the loop
+ if (completedChunks == chunks.size()) {
+ System.out.println("Download completed!");
+ break;
+ }
try {
Thread.sleep(monitorDelayMs);
} catch (InterruptedException e) {
- System.out.println("Progress monitor interrupted.");
- return;
+ e.printStackTrace();
}
}
}
-}
+}
\ No newline at end of file