Files

355 lines
14 KiB
TeX
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
\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}