Final version of project
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
# Report - Multithreading Assignment
|
||||
|
||||
## 1. Difference Between start() and run()
|
||||
|
||||
In Java, both `start()` and `run()` are related to threads, but they behave differently.
|
||||
|
||||
When we call the `run()` method directly, no new thread is created. The method runs like a normal method in the current thread, usually the main thread.
|
||||
|
||||
When we call the `start()` method, Java creates a new thread and then executes the `run()` method inside that new thread.
|
||||
|
||||
Example:
|
||||
```java
|
||||
Thread t1 = new Thread(() -> {
|
||||
System.out.println("Thread 1: " + Thread.currentThread().getName());
|
||||
});
|
||||
|
||||
Thread t2 = new Thread(() -> {
|
||||
System.out.println("Thread 2: " + Thread.currentThread().getName());
|
||||
});
|
||||
|
||||
t1.run();
|
||||
t2.start();
|
||||
|
||||
Possible output:
|
||||
|
||||
text
|
||||
Thread 1: main
|
||||
Thread 2: Thread-0
|
||||
|
||||
In this output, `t1.run()` runs in the main thread, but `t2.start()` runs in a separate thread.
|
||||
|
||||
So, the main difference is:
|
||||
|
||||
- `run()` executes the code normally in the current thread.
|
||||
- `start()` creates a new thread and runs the code concurrently.
|
||||
|
||||
## 2. Daemon Threads
|
||||
|
||||
A daemon thread is a background thread that does not prevent the program from exiting.
|
||||
|
||||
If only daemon threads are still running and all normal user threads finish, the JVM stops the program automatically.
|
||||
|
||||
Example:
|
||||
|
||||
java
|
||||
Thread daemonThread = new Thread(() -> {
|
||||
while (true) {
|
||||
System.out.println("Daemon thread is running...");
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
daemonThread.setDaemon(true);
|
||||
daemonThread.start();
|
||||
|
||||
System.out.println("Main thread finished.");
|
||||
|
||||
Possible output:
|
||||
|
||||
text
|
||||
Main thread finished.
|
||||
Daemon thread is running...
|
||||
|
||||
The daemon thread may stop immediately after the main thread finishes because the JVM does not wait for daemon threads.
|
||||
|
||||
If we remove this line:
|
||||
|
||||
java
|
||||
daemonThread.setDaemon(true);
|
||||
|
||||
then the thread becomes a normal user thread. In that case, the program may not stop because the infinite loop keeps running.
|
||||
|
||||
Real-life examples of daemon threads:
|
||||
|
||||
- Garbage Collector in Java
|
||||
- Background monitoring tasks
|
||||
- Auto-save services
|
||||
- Log cleanup tasks
|
||||
- Background cache cleanup
|
||||
|
||||
Daemon threads are useful for background tasks that should not block the application from closing.
|
||||
|
||||
## 3. Lambda Expressions and Runnable
|
||||
|
||||
The syntax `() -> { ... }` is called a lambda expression.
|
||||
|
||||
In Java, lambda expressions can be used to write shorter code for functional interfaces such as `Runnable`.
|
||||
|
||||
Traditional way:
|
||||
|
||||
java
|
||||
Runnable task = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("Task is running");
|
||||
}
|
||||
};
|
||||
|
||||
Thread thread = new Thread(task);
|
||||
thread.start();
|
||||
|
||||
Lambda way:
|
||||
|
||||
java
|
||||
Runnable task = () -> {
|
||||
System.out.println("Task is running");
|
||||
};
|
||||
|
||||
Thread thread = new Thread(task);
|
||||
thread.start();
|
||||
|
||||
Output:
|
||||
|
||||
text
|
||||
Task is running
|
||||
|
||||
Both versions do the same thing, but the lambda version is shorter and cleaner.
|
||||
|
||||
The lambda expression is useful because `Runnable` has only one abstract method: `run()`.
|
||||
|
||||
Main differences:
|
||||
|
||||
- Traditional implementation needs an anonymous class.
|
||||
- Lambda expression uses shorter syntax.
|
||||
- Lambda expression makes the code easier to read.
|
||||
- Both can be used to create and run threads.
|
||||
|
||||
## 4. Practical Part Explanation
|
||||
|
||||
In the practical part of this assignment, a simulated download manager was implemented using multithreading.
|
||||
|
||||
The file is divided into several chunks. Each chunk is downloaded by a separate worker thread. Each worker updates its own `ChunkStatus`.
|
||||
|
||||
The `ProgressMonitor` runs separately and checks the progress of all chunks. It calculates the total downloaded size and prints the progress percentage until the download reaches 100%.
|
||||
|
||||
The configuration values are read from `download_config.txt`, such as file size, number of chunks, delay range, download step range, and monitor delay.
|
||||
|
||||
This project demonstrates the basic concepts of multithreading, including:
|
||||
|
||||
- Creating multiple threads
|
||||
- Running tasks concurrently
|
||||
- Monitoring shared progress
|
||||
- Waiting for threads to finish
|
||||
- Simulating a real download manager
|
||||
|
||||
|
||||
Reference in New Issue
Block a user