Update README

This commit is contained in:
2026-06-05 23:02:51 +03:30
parent 3111f23b1c
commit 7f0406b2aa
+57 -124
View File
@@ -1,41 +1,3 @@
# Eighth Assignment: Multithreading Basics
## Table of contents
- [Introduction](#introduction)
- [Objectives 🎯](#objectives-)
- [Theoretical Questions 📝](#theoretical-questions-)
- [Practical Questions 💻](#practical-questions-)
- [Evaluation ⚖️](#evaluation-)
- [Submission ⌛](#submission-)
- [Additional Resources 📚](#additional-resources-)
## Important Note:
This project is configured as a **Maven project**. If you're opening this project in an IDE (like IntelliJ IDEA or VS Code), please ensure you import it as a Maven project so that dependencies and build settings are recognized automatically.
To run the project from the command line, use:
```bash
mvn compile
mvn exec:java -Dexec.mainClass="Main"
```
## Introduction
Welcome to your Eighth Advanced Programming (AP) Assignment. This project is divided into two main sections:
1. **Theoretical Questions**: Analyze key multithreading concepts (Start vs Run, Daemon threads, and Lambdas).
2. **Practical Questions**: Implement a **Simulated Download Manager**. You will use Java Threads to simulate downloading a file in multiple chunks concurrently.
> **⚠️ Note:** This is a **local simulation only**. There is no actual network activity, URL connection, or socket programming involved. The goal is to practice thread management and state observation.
## Objectives 🎯
By completing this assignment, you will:
- Apply **multithreading** basics using the `Thread` class and `Runnable` interface.
- Understand how to manage multiple worker threads performing independent tasks.
- Implement a monitor thread to observe the progress of other threads.
- Practice using `start()` and `join()` for thread lifecycle management.
## Theoretical Questions 📝
**Note: Please answer these questions in a Markdown file (Report.md) and place it in the root directory of your fork. Include code or screenshots where you see fit.**
### 1. `start()` vs `run()` ### 1. `start()` vs `run()`
@@ -61,14 +23,26 @@ public class StartVsRun {
**Questions:** **Questions:**
- What output do you get from the program? Why? - ##### What output do you get from the program? Why?
- Whats the difference in behavior between calling `start()` and `run()`?
--- - ##### Whats the difference in behavior between calling `start()` and `run()`?</br>
**answers :**
```
Calling run()
Running in: main
Calling start()
Running in: Thread-2
```
Because when we call " **t1.run()** ", it does not create a new thread. we have just called run method in class main so it prints "**Running in: main**".
</br>
But when we call " **t2.start()** " it creates a new thread and it calls the run method of this object on the new thread so it prints "**Running in: Thread-2**"
---
### 2. Daemon Threads ### 2. Daemon Threads
```java ```java
public class DaemonExample { public class DaemonExample {
static class DaemonRunnable implements Runnable { static class DaemonRunnable implements Runnable {
@@ -93,14 +67,37 @@ public class DaemonExample {
``` ```
**Questions:** **Questions:**
- What output do you get from the program? Why? - ##### What output do you get from the program? Why?
- What happens if you remove `thread.setDaemon(true)`? **answer :**
- What are some real-life use cases of daemon threads? output :
```
Main thread ends.
Daemon thread running...
```
because the Main Thread finishes quickly but the Daemon tries to print messages for 20 times so the JVM kills the Daemon Thread abruptly, even if it hasnt finished its work.
--- - ##### What happens if you remove `thread.setDaemon(true)`?
**answer :**</br>
Even though the main thread finishes, the JVM keeps the program running until the new User Thread completes its 20 iterations. The full output will be printed.
- ##### What are some real-life use cases of daemon threads?</br>
**answer :**</br>
- _**Garbage Collection:**_</br>
The JVM itself uses daemon threads for memory cleanup. They run in the background to free up occupied memory so the main application can continue running smoothly.
- **_Logging:_**</br>
Threads that write log messages to files are often daemons. This ensures that if the main application shuts down abruptly, the logging process doesnt block it or cause delays.
- **_Health Checks:_**</br>
Services that periodically check if the system is healthy (such as verifying database connectivity) usually run as daemon threads.
- **_Pre-loading:_**</br>
When an application is starting up, daemon threads can prepare necessary data in advance. This helps improve the speed and responsiveness of the application once its fully loaded.
---
### 3. A shorter way to create threads ### 3. A shorter way to create threads
@@ -117,86 +114,22 @@ public class ThreadDemo {
``` ```
**Questions:** **Questions:**
- What output do you get from the program?
- What is the `() -> { ... }` syntax called? - ##### What output do you get from the program?
- How is this code different from creating a class that extends `Thread` or implements `Runnable`? **answer:**</br>
output:
```
Thread is running using a ...!
```
- ##### What is the `() -> { ... }` </br>
## Practical Questions 💻 **answer:**</br>
This syntax is called a Lambda Expression. It provides a concise way to represent instances of functional interfaces (interfaces with only one abstract method).
- #### How is this code different from creating a class that extends `Thread` or implements `Runnable`?
### Simulated Download Manager **answer:**</br>
You are tasked with completing a skeleton project for a download manager. The application reads a configuration file, splits a "file" into several chunks, and assigns each chunk to a dedicated worker thread. **Less Code:** With Lambda, you dont need to create a separate class (either extending Thread or implementing Runnable) and override the run() method. You write the logic directly inside the Thread constructor.
#### 🏗 Project Structure **Flexibility:** While extending Thread forces you to create a new class hierarchy, and implementing Runnable requires an extra class or anonymous inner class, Lambda allows you to pass the behavior directly as an argument.
- `src/main/resources/download_config.txt`: Contains simulation parameters (file size, chunk count, delays).
- `DownloadWorker.java`: The logic for simulating a chunk download (needs implementation).
- `ProgressMonitor.java`: A thread that periodically prints the total progress (needs implementation).
- `Main.java`: The entry point that initializes chunks, starts threads, and waits for completion.
- `ChunkStatus.java`: Data class holding the state of individual chunks.
#### 🛠 What You Need to Do
In the provided source code, look for **`// TODO`** comments. You must:
1. **Implement `DownloadWorker`**:
- Record start/end times for each chunk.
- Use a loop to simulate progress based on the random delays and step sizes provided in the config.
- Update the shared `ChunkStatus` object so the monitor can see progress.
2. **Implement `ProgressMonitor`**:
- Periodically calculate the total downloaded megabytes across all chunks.
- Exit gracefully once all chunks are marked as completed.
3. **Complete `Main`**:
- Properly instantiate and `start()` the worker threads and the monitor thread.
- Use `join()` to ensure the main thread waits for all workers to finish before printing the final report.
#### ⚙️ Configuration
The simulation behavior is controlled by `src/main/resources/download_config.txt`. You can modify these values to test different scenarios (e.g., more chunks or faster/slower speeds).
---
## Bonus Tasks 🌟
- Download Speed and ETA:
- Calculate and display the current overall download speed during the simulation.
- Estimate and show the remaining time (ETA) based on the current progress and speed.
- User Interface (UI):
- Improve the console output or design a simple UI that presents download progress in a cleaner and more intuitive way.
- Make the simulation easier to follow by showing chunk activity, total progress, and final results in a user-friendly format.
- Real-Time Progress Bar:
- Implement a real-time progress bar that updates in place instead of printing a new line each time.
- Show smooth progress growth in the console so the output looks more like a real download manager.
- Sequential vs Multithreaded Comparison:
- Add a mode to simulate downloading chunks sequentially (one after another) and compare it with the multithreaded version.
- Measure and report the total execution time of both approaches, and briefly analyze the difference in performance.
## Evaluation ⚖️
Your work will be evaluated based on:
- **Thread Management**: Correct use of `start()` and `join()`.
- **Simulation Logic**: Correct implementation of the loops and random delays in the worker threads.
- **Thread Safety**: Following the constraint of each worker only writing to its own assigned object.
- **Code Quality**: Readable code and proper use of Java conventions.
**Total: 500 points**
- 🧠 Theoretical Questions 150 points
- 💻 Practical Task (Download Manager) 350 points
## Submission ⌛
1. Add your mentor as a contributor to the project.
2. Create a `develop` branch for implementing features.
3. Use Git for regular code commits.
4. Push your code and the answers file (Report.md) to the remote repository.
5. Submit a pull request to merge the `develop` branch with `main`.
**Deadline:** **Friday, June 5** (15th of Khordad)
## Additional Resources 📚
- [Java Concurrency and Multithreading](https://jenkov.com/tutorials/java-concurrency/index.html)
- [Creating and Starting Java Threads](https://jenkov.com/tutorials/java-concurrency/creating-and-starting-threads.html)
- [Thread.join() explained](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join--)