- A thread is the smallest unit of execution inside a process.
- Every Java program starts with one thread the main thread.
- A process = a company.
- A thread = an employee
CreateWithLamda.javaCreateWithRunnable.javaCreateWithThread.java
NEW → RUNNABLE → RUNNING → BLOCKED → TERMINATED
- NEW
- When thread is created but not started yet.
- Thread object exists, but start() hasn’t been called.
- RUNNABLE
- When CPU starts executing the thread’s run() method.
- The thread is actively executing code.
- BLOCKED / WAITING / TIMED_WAITING
- When the thread is paused
- Happens during sleep(), wait(), or waiting for lock.
- TERMINATED (DEAD)
- When run() finishes or throws an exception.
- The thread has completed execution.
sleep(), join(), yield(), setPriority(), getPriority(),
isAlive(), getName(), setName()
-
join()- You have 3 threads:
Imagine we have three threads: T1, T2, and T3. Now, suppose T1 calls
T2.join(). This means that T1 will pause its execution and wait until T2 finishes its work. While T1 is waiting, T2 continues to run normally, and T3 remains completely independent, continuing its work without any interruption. Once T2 finishes execution, thejoin()call in T1 unblocks, allowing T1 to resume from where it left off. This mechanism is often used when one thread needs to wait for another to complete before proceeding.
- You have 3 threads:
Imagine we have three threads: T1, T2, and T3. Now, suppose T1 calls
-
yeild()- It tells the CPU scheduler it’s willing to pause. The thread goes from Running → Runnable (ready state). The scheduler may pick another thread of equal or higher priority to run next. Or, it might immediately pick the same thread again because it’s only a suggestion, not a command. The CPU scheduler may or may not listen to it. — so sometimes it looks like nothing happened.
-
sleep(ms)- Actually pauses for a fixed time.
There are mainly two types of lock in java Intrinsic and explicit lock. Every java object including the object class has uses the intrinsic lock
- When synchronized keyword is being used the java primarly use the intrinsic lock.
- the synchronized uses
intrinsiclock on object to acquire the lock. Thethreadhas to wait indefinitely for its turn.
- the synchronized uses
- We (developer) has not control over it to
unlockortimeout, it that scenario we haveexplicitlock. - In Java we have
Lockinterface andReentrantLockimplementor. - In
Lockwe have multiple methods but mainly I usedlock(),unlock(),trylock(),lockInterruptibly()trylock(long time, TimeUnit unit)
- The thread who acquires the lock is owner of the lock, the same thread can acquire as many locks as it can, however it has to unlock those same locks as many times it has acquired.
- Internally the initial value is
0when you use thelock()it increment by1if the same thread acquire3locks it has tounlock()3 times to release the complete lock. if you miss anyunlock()method, then program will hang up forever try programLock1_Exampleand comment the line// comment B method unlock method, but that's not in synchronized block check exampleSynchronizedBlock2_Exampleonce thread enters in synchronized block it will complete the entire block / method body because we do not have control over it, that's why it is called intrinsic lock.
- If there are two threads thread-1 and thread-2. When thread-1 acquire the lock and thread-2 will try for the lock but thread-1 already has it, so the
tryLock()will returnfalseand thread-2 will not wait but immediately stop. try exampleLock3_TryLockExample, Withsynchronizedthread-2 always waits until the lock is released, no option to skip or timeout.
- The thread-2 will wait for given time, if it gets lock then it will complete the task otherwise, it will be stopped. try example
Lock4_TryLockTimeoutExample
- Parallel Sum Calculator use of
ExecutorService,Callable,Future - Bank Account Simulation use of
Lock,Reentrantlock,AtomicInteger- Multiple threads deposit and withdraw safely.
- To check the difference in output uncomment the code from line
25to29 -
// try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // }