🧭 Topic: Hashing & Multithreading

Quick Overview :

This topic introduces hashing concepts and multithreaded programming in Java. It covers hash functions, the equals/hashCode contract, thread creation and lifecycle, concurrency vs parallelism, and practical applications of multithreading with thread management techniques.


📌 Covered in This Topic

Hashing Fundamentals

What is Hashing?

  • A hash function is a mathematical algorithm that converts any input into a fixed-size string of bytes
  • Designed to be a one-way function – computationally infeasible to reverse the process and obtain the original input from the hash value
  • Cryptographic hash functions provide additional security properties

Important Hash Functions

  • SHA hash functions (SHA-256): Widely used in Digital Signature algorithms
  • MD5 (Message Digest 5): Used in software products to ensure Data Integrity
  • Crypt: Hash function designed for Password Hashing and storage
    • Adds an additional layer of security – even if two users have the same password, their hashed passwords will be different
    • JBCrypt package in Java can be used to hash passwords

Collision

  • Occurs when two different inputs produce the same hash value
  • Collision Resistance is one of the properties of cryptographic hash functions

Why Hashing Relies on equals()

  • Hashing is not a perfect filter – hash functions are designed for speed, not uniqueness
  • When hash code points to a specific “bucket,” the system must use equals() to verify if the object retrieved is truly the one requested
  • equals() acts as the final gatekeeper to distinguish between two different objects that happen to share the same hash value

The equals() and hashCode() Contract

  • The Logic:
    • Hashing identifies a “potential” match
    • equals() confirms the “exact” match
  • Consequences of a broken contract:
    • If two objects are equal by equals() but have different hashCode(), the hashing system fails to find them
    • The object exists but becomes “invisible” to the system

Multithreading Concepts

Definitions

  • Program: A bunch of ones and zeros on hard disk (static state)
  • Process: When a program is loaded into memory (RAM), it becomes a process with a dedicated ID
  • OS: The only program that is always running and decides what other programs should do
  • Multithreading: Multiple threads executing concurrently within a single process

Why Use Multithreading?

  • Increase Responsiveness: Allows continued execution if part of the process is blocked
  • Resource Sharing: Threads share memory and resources of the process
  • Economy: Thread creation is cheaper than process creation, thread switching has lower cost
  • Scalability: Can take advantage of multiprocessor architectures by running on multiple cores

Concurrency vs Parallelism

  • Concurrency: Multiple tasks making progress simultaneously (interleaved execution)
  • Parallelism: Multiple tasks executing simultaneously (true simultaneous execution)

GPU vs CPU

  • CPU: Fewer strong cores
  • GPU: Thousands weaker cores – optimized for parallel processing

Multithreading in Java

How Java Manages Threads

  • Java threads are managed by the JVM
  • JVM threads are mapped to native OS threads
  • Uses the Operating System’s threading model (e.g., Windows, Linux)
  • JVM acts as an abstraction layer but relies on the OS for actual scheduling and execution

Creating Threads – Two Approaches

1. Extending the Thread class:

class MyThread extends Thread {
    public void run() {
        System.out.println("Thread running: " + 
            Thread.currentThread().getName());
    }
}
// Usage
MyThread t1 = new MyThread();
t1.start();

2. Implementing the Runnable interface:

class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Runnable running: " + 
            Thread.currentThread().getName());
    }
}
// Usage
Thread t2 = new Thread(new MyRunnable());
t2.start();

Thread Lifecycle States

StateMeaningExample Method
NEWCreated but not startednew Thread()
RUNNABLEReady or running.start()
BLOCKEDWaiting for monitor lockssynchronized blocked
WAITINGWaiting indefinitelywait(), join()
TIMED_WAITINGWaiting with timeoutsleep(), wait(1000)
TERMINATEDFinished or crashedAfter run() completes

How to Stop Threads Safely

  • The Thread.stop() method is deprecated – provides no guarantees about the state in which the thread was stopped
  • Safe Approach: Using Interrupts
    • Threads should check if they’ve been interrupted using Thread.interrupted() or isInterrupted()
    • Interrupting signals the thread to stop itself gracefully

Useful Thread Methods

MethodDescription
start()Starts a new thread and calls run()
run()Code that runs in the thread; don’t call directly
sleep(ms)Puts thread to sleep for specified milliseconds
join()Waits for a thread to die before continuing
isAlive()Checks if the thread is still running
setName() / getName()Sets or gets thread name
setPriority(int)Sets thread priority (MIN/NORM/MAX)
yield()Suggests current thread pause and let others run
interrupt()Interrupts a sleeping/waiting thread
isInterrupted()Checks if a thread was interrupted

📑 Slides & Materials


🛠️ Workshop & Assignments

💬 Workshop: Mini Student Search Engine

  • 📂 WS-07-Multithreading-Basics-and-Hashing
  • Objective: Build a student search engine that reads from file, processes with multiple threads, and supports search operations
  • Part 1 – Student Class:
    • Create Student with fields: int id, String name, String major, double gpa
    • Override hashCode() (use id % 97), equals() (compare IDs), and toString()
    • Do NOT use Objects.hash()
  • Part 2 – StudentLoader Thread:
    • StudentLoader extends Thread
    • Each thread receives part of file lines
    • Reads assigned lines, creates Student objects, stores in its own list
    • No shared lists – each thread maintains its own ArrayList
    • Do NOT use synchronized, Lock, Semaphore, or ExecutorService
  • Part 3 – Merge Results:
    • After threads finish, use thread.join() for each
    • Combine all lists into final list
  • Required Menu: Load, Search, Remove, Print, Exit
  • Restrictions: No HashMap, HashSet, TreeMap, ConcurrentHashMap; no synchronized, wait(), notify(); no Lock, Semaphore, ExecutorService

🧮 Assignment: Basic Multithreading

  • 📂 HW-08-Basic-Multithreading
  • Structure: Theoretical Questions + Practical Implementation
  • Theoretical Questions (Report.md):
    1. start() vs run(): Analyze behavior and differences
    2. Daemon Threads: Analyze program output, behavior with/without daemon, real-life use cases
    3. Lambdas: Analyze code using lambda expressions for thread creation
  • Practical Task – Simulated Download Manager:
    • Read config file (download_config.txt) with parameters
    • DownloadWorker: Simulate chunk downloads with loops, random delays, record start/end times
    • ProgressMonitor: Periodically calculate total progress, exit when complete
    • Main: Instantiate and start workers and monitor, use join() to wait
  • Bonus Tasks:
    • Download speed and ETA calculation
    • Improved console UI or simple UI
    • Real-time progress bar
    • Sequential vs multithreaded comparison
  • Evaluation: 500 points (150 theory + 350 practical)
  • Deadline: Friday, June 5 (15th of Khordad)

RepositoryDescription
📂 WS-07-Multithreading-Basics-and-HashingWorkshop: Student search engine with multithreading and hashing
📂 HW-08-Basic-MultithreadingAssignment: Theoretical questions + Simulated Download Manager

🌐 Additional Resources


⏩ Navigation


Tip :

When working with multithreading, always remember the equals()/hashCode() contract – breaking it leads to objects becoming “invisible” in collections. For thread safety, avoid shared mutable state when possible. The workshop restrictions (no synchronized, no ExecutorService) are designed to help you understand the fundamentals of thread management before using higher-level abstractions. Practice with simple thread examples before tackling the download manager simulation!