355 lines
14 KiB
TeX
355 lines
14 KiB
TeX
\documentclass[12pt,a4paper]{article}
|
||
|
||
\usepackage[utf8]{inputenc}
|
||
\usepackage[T1]{fontenc}
|
||
\usepackage[margin=2.5cm]{geometry}
|
||
\usepackage{listings}
|
||
\usepackage{xcolor}
|
||
\usepackage{hyperref}
|
||
\usepackage{parskip}
|
||
\usepackage{booktabs}
|
||
\usepackage{array}
|
||
\usepackage{titlesec}
|
||
\usepackage{fancyhdr}
|
||
\usepackage{amsmath}
|
||
\usepackage{enumitem}
|
||
|
||
% ── Page style ──────────────────────────────────────────────────────────────
|
||
\pagestyle{fancy}
|
||
\fancyhf{}
|
||
\rhead{Advanced Programming – Assignment 8}
|
||
\lhead{Faraz Ardeh}
|
||
\cfoot{\thepage}
|
||
|
||
% ── Section formatting ───────────────────────────────────────────────────────
|
||
\titleformat{\section}{\large\bfseries}{Question \thesection.}{0.6em}{}
|
||
\titleformat{\subsection}{\normalsize\bfseries}{}{0em}{}
|
||
|
||
% ── Java code style ─────────────────────────────────────────────────────────
|
||
\definecolor{javakw}{rgb}{0.13,0.13,0.60}
|
||
\definecolor{javastr}{rgb}{0.63,0.13,0.13}
|
||
\definecolor{javacmt}{rgb}{0.38,0.38,0.38}
|
||
\definecolor{codebg}{rgb}{0.97,0.97,0.97}
|
||
\definecolor{codefr}{rgb}{0.82,0.82,0.82}
|
||
|
||
\lstdefinestyle{java}{
|
||
language=Java,
|
||
basicstyle=\ttfamily\small,
|
||
keywordstyle=\color{javakw}\bfseries,
|
||
stringstyle=\color{javastr},
|
||
commentstyle=\color{javacmt}\itshape,
|
||
numberstyle=\tiny\color{gray},
|
||
numbers=left,
|
||
stepnumber=1,
|
||
numbersep=8pt,
|
||
backgroundcolor=\color{codebg},
|
||
frame=single,
|
||
rulecolor=\color{codefr},
|
||
breaklines=true,
|
||
breakatwhitespace=false,
|
||
showstringspaces=false,
|
||
tabsize=4,
|
||
captionpos=b,
|
||
}
|
||
|
||
\lstset{style=java}
|
||
|
||
% ── Inline code ─────────────────────────────────────────────────────────────
|
||
\newcommand{\code}[1]{\texttt{\small #1}}
|
||
|
||
% ────────────────────────────────────────────────────────────────────────────
|
||
\begin{document}
|
||
|
||
% ── Title page ───────────────────────────────────────────────────────────────
|
||
\begin{titlepage}
|
||
\centering
|
||
\vspace*{3cm}
|
||
{\Huge\bfseries Multithreading Basics\par}
|
||
\vspace{0.8cm}
|
||
{\large Assignment 8 – Theoretical Questions\par}
|
||
\vspace{0.4cm}
|
||
{\large Advanced Programming (AP)\par}
|
||
\vspace{2cm}
|
||
\rule{0.6\linewidth}{0.5pt}\\[0.4cm]
|
||
{\large\bfseries Faraz Ardeh\par}
|
||
\vspace{0.3cm}
|
||
{\normalsize fa.ardeh@gmail.com\par}
|
||
\vspace{0.6cm}
|
||
{\normalsize Shahid Beheshti University\par}
|
||
\vspace{0.3cm}
|
||
{\normalsize June 2026\par}
|
||
\vfill
|
||
\end{titlepage}
|
||
|
||
\tableofcontents
|
||
\newpage
|
||
|
||
% ════════════════════════════════════════════════════════════════════════════
|
||
\section{\code{start()} vs \code{run()}}
|
||
% ════════════════════════════════════════════════════════════════════════════
|
||
|
||
The program under analysis:
|
||
|
||
\begin{lstlisting}[caption={StartVsRun.java}]
|
||
public class StartVsRun {
|
||
static class MyRunnable implements Runnable {
|
||
public void run() {
|
||
System.out.println("Running in: " + Thread.currentThread().getName());
|
||
}
|
||
}
|
||
public static void main(String[] args) throws InterruptedException {
|
||
Thread t1 = new Thread(new MyRunnable(), "Thread-1");
|
||
System.out.println("Calling run()");
|
||
t1.run();
|
||
Thread.sleep(100);
|
||
|
||
Thread t2 = new Thread(new MyRunnable(), "Thread-2");
|
||
System.out.println("Calling start()");
|
||
t2.start();
|
||
}
|
||
}
|
||
\end{lstlisting}
|
||
|
||
\subsection{Expected output}
|
||
|
||
\begin{lstlisting}[language={},numbers=none,backgroundcolor=\color{codebg}]
|
||
Calling run()
|
||
Running in: main
|
||
Calling start()
|
||
Running in: Thread-2
|
||
\end{lstlisting}
|
||
|
||
\subsection{Why this output?}
|
||
|
||
\textbf{The \code{t1.run()} call:}
|
||
Calling \code{run()} on a \code{Thread} object is just an ordinary method call, exactly
|
||
like calling any other method on any other object.
|
||
No new OS thread is created or scheduled.
|
||
The body of \code{run()} executes \emph{synchronously} inside the calling thread,
|
||
which is \code{main}.
|
||
Therefore \code{Thread.currentThread().getName()} returns \texttt{"main"},
|
||
not \texttt{"Thread-1"}.
|
||
The thread object \texttt{t1} was constructed but its native thread was never started.
|
||
|
||
\textbf{The \code{t2.start()} call:}
|
||
\code{start()} allocates a new OS-level thread, registers it with the JVM scheduler,
|
||
and returns to the caller \emph{immediately} (it does not wait for \code{run()} to finish).
|
||
The new thread then invokes \code{run()} autonomously and concurrently.
|
||
Inside that new thread, \code{Thread.currentThread().getName()} correctly
|
||
returns \texttt{"Thread-2"}.
|
||
|
||
\subsection{Key differences at a glance}
|
||
|
||
\begin{center}
|
||
\begin{tabular}{>{\bfseries}lll}
|
||
\toprule
|
||
Aspect & \code{run()} & \code{start()} \\
|
||
\midrule
|
||
New thread created? & No & Yes (exactly one) \\
|
||
Execution thread & Current thread & New thread \\
|
||
Blocking behaviour & Synchronous (caller waits) & Asynchronous (returns at once) \\
|
||
Can be called twice? & Yes, legal & No – throws \code{IllegalThreadStateException} \\
|
||
Useful for? & Testing \code{run()} logic directly & True concurrent execution \\
|
||
\bottomrule
|
||
\end{tabular}
|
||
\end{center}
|
||
|
||
\textbf{Summary:}
|
||
\code{run()} is simply a method call; \code{start()} is what actually creates and
|
||
launches a new thread of execution. Calling \code{run()} instead of \code{start()} is
|
||
one of the most common multithreading bugs in Java – the code compiles and
|
||
"works", but no concurrency ever happens.
|
||
|
||
% ════════════════════════════════════════════════════════════════════════════
|
||
\section{Daemon Threads}
|
||
% ════════════════════════════════════════════════════════════════════════════
|
||
|
||
\begin{lstlisting}[caption={DaemonExample.java}]
|
||
public class DaemonExample {
|
||
static class DaemonRunnable implements Runnable {
|
||
public void run() {
|
||
for (int i = 0; i < 20; i++) {
|
||
System.out.println("Daemon thread running...");
|
||
try {
|
||
Thread.sleep(500);
|
||
} catch (InterruptedException e) {
|
||
// [Handling Exception...]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
public static void main(String[] args) {
|
||
Thread thread = new Thread(new DaemonRunnable());
|
||
thread.setDaemon(true);
|
||
thread.start();
|
||
System.out.println("Main thread ends.");
|
||
}
|
||
}
|
||
\end{lstlisting}
|
||
|
||
\subsection{Expected output (with \code{setDaemon(true)})}
|
||
|
||
\begin{lstlisting}[language={},numbers=none,backgroundcolor=\color{codebg}]
|
||
Main thread ends.
|
||
Daemon thread running...
|
||
(program terminates -- usually 0-2 more lines, non-deterministic)
|
||
\end{lstlisting}
|
||
|
||
\textbf{Why?}
|
||
The JVM shuts down when there are no \emph{non-daemon} threads still alive.
|
||
After \code{main()} prints \texttt{"Main thread ends."} and returns, the only surviving
|
||
thread is the daemon thread.
|
||
Because it is marked as a daemon, the JVM does \emph{not} wait for it to
|
||
finish – it exits immediately (or after one scheduling quantum), abruptly
|
||
terminating the daemon thread.
|
||
The daemon may manage to print zero, one, or a few lines before termination,
|
||
depending entirely on OS thread scheduling; this is non-deterministic.
|
||
|
||
\subsection{What happens if you remove \code{thread.setDaemon(true)}?}
|
||
|
||
Without that call the thread becomes a regular \emph{user thread} (the default).
|
||
The JVM rule is: \textbf{wait for all user threads to finish before exiting.}
|
||
The daemon thread (now a user thread) will sleep 500 ms per iteration and
|
||
loop 20 times – the program will take approximately $20 \times 0.5 = 10$ seconds
|
||
to terminate, and all 20 lines of \texttt{"Daemon thread running..."} will be
|
||
printed in full before the JVM exits.
|
||
|
||
\subsection{Real-life use cases of daemon threads}
|
||
|
||
Daemon threads are ideal for background housekeeping work that should not
|
||
prevent the application from exiting cleanly.
|
||
|
||
\begin{enumerate}[leftmargin=2em]
|
||
\item \textbf{Garbage Collection.}
|
||
The JVM's garbage collector runs as a daemon thread;
|
||
it must not keep the JVM alive on its own.
|
||
|
||
\item \textbf{Log flushing.}
|
||
A background thread that periodically flushes buffered log entries
|
||
to disk. If the application finishes, unsaved logs are
|
||
an acceptable loss compared with hanging the process.
|
||
|
||
\item \textbf{Cache invalidation / expiry.}
|
||
A thread that sweeps an in-memory cache and removes stale entries
|
||
does not need to outlive the application.
|
||
|
||
\item \textbf{Heartbeat / health-check threads.}
|
||
Service-mesh sidecars and microservices often send periodic
|
||
pings to a service-discovery system.
|
||
These should die with the service, not keep it alive.
|
||
|
||
\item \textbf{IDE background indexing.}
|
||
IntelliJ IDEA's indexer and VS Code's language-server workers
|
||
are typically daemon-like: if you close the IDE, you do not
|
||
want to wait for them to finish indexing.
|
||
\end{enumerate}
|
||
|
||
% ════════════════════════════════════════════════════════════════════════════
|
||
\section{A Shorter Way to Create Threads – Lambda Expressions}
|
||
% ════════════════════════════════════════════════════════════════════════════
|
||
|
||
\begin{lstlisting}[caption={ThreadDemo.java}]
|
||
public class ThreadDemo {
|
||
public static void main(String[] args) {
|
||
Thread thread = new Thread(() -> {
|
||
System.out.println("Thread is running using a lambda!");
|
||
});
|
||
|
||
thread.start();
|
||
}
|
||
}
|
||
\end{lstlisting}
|
||
|
||
\subsection{Expected output}
|
||
|
||
\begin{lstlisting}[language={},numbers=none,backgroundcolor=\color{codebg}]
|
||
Thread is running using a lambda!
|
||
\end{lstlisting}
|
||
|
||
\subsection{What is \code{() -> \{ \ldots \}} called?}
|
||
|
||
The \code{() -> \{ \ldots \}} syntax is called a \textbf{lambda expression}
|
||
(also known as an \emph{anonymous function} or \emph{arrow function} in
|
||
other languages).
|
||
|
||
A lambda expression is a concise way to provide an implementation of a
|
||
\emph{functional interface} – any interface that declares exactly one abstract
|
||
method.
|
||
\code{Runnable} is a functional interface: its single abstract method is
|
||
\code{void run()}.
|
||
The lambda \code{() -> \{ \ldots \}} supplies that implementation inline,
|
||
without naming it.
|
||
|
||
\subsection{How does this differ from other approaches?}
|
||
|
||
There are three common ways to supply a \code{Runnable} to a \code{Thread}:
|
||
|
||
\begin{lstlisting}[caption={Three equivalent approaches}]
|
||
// 1. Class that extends Thread
|
||
class MyThread extends Thread {
|
||
public void run() { System.out.println("extends Thread"); }
|
||
}
|
||
new MyThread().start();
|
||
|
||
// 2. Named class that implements Runnable
|
||
class MyRunnable implements Runnable {
|
||
public void run() { System.out.println("implements Runnable"); }
|
||
}
|
||
new Thread(new MyRunnable()).start();
|
||
|
||
// 3. Lambda expression (shortest)
|
||
new Thread(() -> System.out.println("lambda")).start();
|
||
\end{lstlisting}
|
||
|
||
\begin{center}
|
||
\begin{tabular}{>{\bfseries}lllll}
|
||
\toprule
|
||
Approach & Boilerplate & Separate class? & Captures outer vars? & Extensible? \\
|
||
\midrule
|
||
\code{extends Thread} & High & Yes (named) & No & Inherits Thread \\
|
||
\code{implements Runnable} & Medium & Yes (named) & No & Yes \\
|
||
Anonymous class & Medium & Yes (anon.) & Yes (eff.\ final) & Yes \\
|
||
Lambda & \textbf{Minimal} & No & Yes (eff.\ final) & No \\
|
||
\bottomrule
|
||
\end{tabular}
|
||
\end{center}
|
||
|
||
\textbf{Key advantages of lambdas:}
|
||
\begin{itemize}[leftmargin=2em]
|
||
\item \textbf{Conciseness.}
|
||
No need to declare a class, override a method, or write a constructor.
|
||
A single line can create and start a thread.
|
||
|
||
\item \textbf{Readability.}
|
||
The intent (``run this block of code in a new thread'') is immediately
|
||
obvious to the reader.
|
||
|
||
\item \textbf{Variable capture.}
|
||
A lambda can reference local variables from the enclosing scope as long
|
||
as they are effectively final (i.e., never reassigned after declaration).
|
||
This is often more convenient than passing data through a constructor.
|
||
|
||
\item \textbf{Functional programming patterns.}
|
||
Lambdas work seamlessly with the Java Streams API, \code{CompletableFuture},
|
||
\code{ExecutorService}, and other modern concurrency utilities that accept
|
||
\code{Runnable} or \code{Callable} arguments.
|
||
\end{itemize}
|
||
|
||
\textbf{Limitation:}
|
||
Because a lambda is not a subclass of \code{Thread}, it cannot override thread
|
||
life-cycle methods such as \code{interrupt()} or \code{setUncaughtExceptionHandler()}
|
||
directly inside the lambda body.
|
||
When that level of control is needed, a named class is more appropriate.
|
||
|
||
% ── Footer note ──────────────────────────────────────────────────────────────
|
||
\vfill
|
||
\begin{center}
|
||
\small\color{gray}
|
||
Advanced Programming – Assignment 8 \quad|\quad
|
||
Faraz Ardeh \quad|\quad
|
||
Shahid Beheshti University \quad|\quad
|
||
June 2026
|
||
\end{center}
|
||
|
||
\end{document}
|