2 Commits
Author SHA1 Message Date
Aeen 7b9b14317d Merge pull request 'HW08' (#1) from develop into main
Reviewed-on: Arefe00/HW-08-Basic-Multithreading#1
2026-07-30 10:54:16 +00:00
Arefe Talebi 4793e2cef4 HW08 2026-06-24 18:53:41 +03:30
4 changed files with 150 additions and 58 deletions
+71
View File
@@ -0,0 +1,71 @@
Report
1. start() vs run()
What output do you get from the program? Why?
The output is usually something like this:
Calling run()
Running in: main
Calling start()
Running in: Thread-2
When we call "run()" directly, no new thread is created and the code runs in the main thread. That's why "main" is printed.
However, when we call "start()", Java creates a new thread and then executes the "run()" method inside that thread, so the thread name becomes "Thread-2".
What's the difference between calling "start()" and "run()"?
The "run()" method behaves like a normal method call and does not create a new thread.
The "start()" method creates a new thread and allows concurrent execution. Internally, it automatically calls the "run()" method.
---
2. Daemon Threads
What output do you get from the program? Why?
The output is usually:
Main thread ends.
Sometimes a few lines of
Daemon thread running...
may also appear.
This happens because daemon threads run in the background. As soon as the main thread finishes, the JVM stops all daemon threads, even if they have not completed their work.
What happens if you remove "thread.setDaemon(true)"?
If we remove this line, the thread becomes a normal user thread. In this case, the JVM waits until the thread finishes all 20 iterations before terminating the program.
What are some real-life use cases of daemon threads?
Examples include:
- Garbage collection
- Background logging
- Cache cleanup
- Monitoring system resources
- Periodic maintenance tasks
---
3. A shorter way to create threads
What output do you get from the program?
Thread is running using a ...!
What is the "() -> { ... }" syntax called?
This syntax is called a Lambda Expression.
How is this code different from creating a class that extends "Thread" or implements "Runnable"?
Using lambda expressions makes the code shorter and easier to read. Instead of creating a separate class for "Runnable", we can write the thread's behavior directly where we create the thread.
This reduces extra code and makes the program cleaner.
+28
View File
@@ -22,22 +22,50 @@ public class DownloadWorker implements Runnable {
@Override
public void run() {
// TODO: Record the chunk start time in chunkStatus.
chunkStatus.setStartTimeMs(System.currentTimeMillis());
double downloaded = 0.0;
// 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.
int delay = random.nextInt(
config.getMaxStepDelayMs() - config.getMinStepDelayMs() + 1)
+ config.getMinStepDelayMs();
// TODO: Sleep for that delay.
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
// TODO: Generate a random download amount for this step.
double stepDownload =
config.getMinStepDownloadMB() +
(config.getMaxStepDownloadMB() - config.getMinStepDownloadMB()) * random.nextDouble();
// TODO: Increase downloaded, but do not go beyond chunk size.
downloaded += stepDownload;
if (downloaded > chunkStatus.getChunkSizeMB()) {downloaded = chunkStatus.getChunkSizeMB();
}
// TODO: Save the updated downloaded value into chunkStatus.
chunkStatus.setDownloadedMB(downloaded);
// TODO: Optionally print step-by-step progress.
System.out.println(chunkStatus);
}
// TODO: Mark the chunk as completed.
chunkStatus.setCompleted(true);
// TODO: Record the chunk end time in chunkStatus.
chunkStatus.setEndTimeMs(System.currentTimeMillis());
// TODO: Print a message that this chunk has finished downloading.
System.out.println("Chunk #" + chunkStatus.getChunkId() + " finished downloading.");
}
}
+23 -34
View File
@@ -35,8 +35,9 @@ 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
@@ -44,40 +45,28 @@ public class Main {
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();
// 5. Start worker threads
// TODO:
// Start each worker thread in workerThreads.
// Use a loop and call start() on each thread.
// 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();
// }
monitorThread.start();
// 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.
for (Thread thread : workerThreads){
thread.start();
}
// TODO:
try{
for (Thread thread : workerThreads) {
thread.join();
}
}
catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
// 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
// TODO:
try {
monitorThread.join();
}catch (InterruptedException e) {
System.out.println("Monitor thread interrupted.");
}
System.out.println();
System.out.println("=== Final Report ===");
@@ -104,4 +93,4 @@ public class Main {
System.out.println("Downloaded total: " + downloadedMB + "/" + config.getTotalSizeMB() + " MB");
System.out.println("Simulation finished.");
}
}
}
+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("All cchunks have been downloadeed.Monitor stopped.");
break;
}
try {
Thread.sleep(monitorDelayMs);