2 Commits
Author SHA1 Message Date
Aryan 265ef1c8b4 Merge pull request 'develop' (#1) from develop into main
Reviewed-on: #1

90 / 100 * 0.7 delay = 63 / 100 (315 / 500)

Theoretical Q3: Missing explanation of the difference between lambda expressions and Runnable/Thread classes.

DownloadWorker: Download progress is increased by a fixed value instead of using a random value from the configuration.
2026-07-04 07:37:35 +00:00
Mobina 28a223b02c develop 2026-06-12 00:21:31 +03:30
5 changed files with 59 additions and 8 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="25" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
+23
View File
@@ -0,0 +1,23 @@
1-
Calling run()
Running in: main
Calling start()
Running in: Thread-2
متود run() فقط داخل main نخ را اجرا می کند اما متود start() نخ را به صورت جداگانه اجرا می کند
2-
Main thread ends.
چون اگر نخ اصلی ای در حال اجرا نباشد Daemon thread ها اجرا نمی شوند
20 بار "Daemon thread running..." چاپ می شود
نمایش درصد پیشرفت یک دانلود Daemon Thread است اما خود دانلود یک نخ اصلی است
3-
Thread is running using a ...!
Lambda
+20
View File
@@ -23,8 +23,11 @@ public class DownloadWorker implements Runnable {
public void run() {
// TODO: Record the chunk start time in chunkStatus.
double downloaded = 0.0;
chunkStatus.setStartTimeMs(System.currentTimeMillis());
chunkStatus.setDownloadedMB(downloaded);
// TODO: Print a message that this chunk has started downloading.
System.out.println("Chunk #" + chunkStatus.getChunkId() + " started downloading.");
while (downloaded < chunkStatus.getChunkSizeMB()) {
// TODO: Generate a random sleep delay between min and max delay.
@@ -33,11 +36,28 @@ public class DownloadWorker implements Runnable {
// 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 = config.getMinStepDelayMs() + random.nextInt(config.getMaxStepDelayMs() - config.getMinStepDelayMs());
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
downloaded+=0.5;
if (downloaded > chunkStatus.getChunkSizeMB())
downloaded = chunkStatus.getChunkSizeMB();
chunkStatus.setDownloadedMB(downloaded);
}
// 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.setEndTimeMs(System.currentTimeMillis());
chunkStatus.setCompleted(true);
System.out.println("Chunk #" + chunkStatus.getChunkId() + " finished downloading.");
}
}
+11 -7
View File
@@ -47,23 +47,27 @@ public class Main {
// 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 t:workerThreads){
t.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 t : workerThreads) {
try {
t.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
// TODO:
// After all workers finish, the monitor thread may also need to stop.
+4
View File
@@ -57,6 +57,10 @@ public class ProgressMonitor implements Runnable {
// TODO:
// If all chunks are completed, print a final message and exit the loop
if(completedChunks==chunks.size()){
System.out.println("Procsses Done!");
break;
}
try {
Thread.sleep(monitorDelayMs);