Complete guide to Java Multithreading/Synchronization
Content to be covered:
- Java Multi-threading
- Synchronized Method & Block in Java
- wait() and notify() methods in Java
- Classical Producer & Consumer Problem in Java
- Thread Life Cycle
- Multi-tasking in Java
What is Java Multi-threading?
public class MultiThreadingInJava { public static void main(String[] args) throws InterruptedException { C1 obj1 = new C1(); obj1.show1(); System.out.println("\n"); C2 obj2 = new C2(); obj2.show2(); } class C1 { void show1() { Scanner obj = new Scanner(System.in); System.out.println("Enter the value of a: "); int a = obj.nextInt(); System.out.println(a); System.out.println("Done with show1()!"); obj.close(); } } class C2 { void show2() { for (int i = 0; i < 10; i++) { System.out.println(i + "- Hey_2!"); } } }
public class MultiThreadingInJava { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new T1(), "T1 Name"); Thread t2 = new Thread(new T2(), "T2 Name"); t1.start(); t2.start(); System.out.println(Thread.currentThread().getName()); System.out.println("Done with work!"); } class T1 extends Thread { void display() { System.out.println("Hello!"); } @Override public void run() { Scanner obj = new Scanner(System.in); System.out.println("Enter the value of a as integer: "); int a = obj.nextInt(); System.out.println(a); System.out.println("Done with T1!"); System.out.println(Thread.currentThread().getName()); obj.close(); } } class T2 implements Runnable { @Override public void run() { System.out.println("Entered in Thread T2: "); for (int i = 0; i < 1000; i++) { System.out.println(i + "- Hey_2!"); // System.out.println(Thread.currentThread().getName()); } System.out.println(Thread.currentThread().getName()); System.out.println("Done with thread T2!"); } }
What are Synchronized Method & Block in Java?
package Unit_03_Concepts; public class SampleClass { public static void main(String[] args) throws InterruptedException { WebCountData obj = new WebCountData(); Thread t1 = new Thread(new Runnable() { @Override public void run() { for(int i = 0; i<1000; i++) { obj.WebCount2(); } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { for(int i = 0; i<1000; i++) { obj.WebCount2(); } } }); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(WebCountData.count); System.out.println(Thread.currentThread().getName()); } } class WebCountData{ static int count = 0; synchronized public void WebCount1() { System.out.println("Inaside WebCount1 Method"); System.out.println("Inaside WebCount1 Method"); System.out.println("Inaside WebCount1 Method"); System.out.println("Inaside WebCount1 Method"); count++; } public void WebCount2() { System.out.println("Inaside WebCount2 Method"); System.out.println("Inaside WebCount2 Method"); System.out.println("Inaside WebCount2 Method"); System.out.println("Inaside WebCount2 Method"); synchronized(this) { count++; } } }
What are wait() and notify() methods in Java?
public class SampleClass { public static void main(String[] args) { SharedResource c = new SharedResource(); new Thread(new Runnable() { @Override public void run() { c.withdraw(15000); } }).start(); new Thread() { public void run() { c.withdraw(15000); } }.start(); new Thread() { public void run() { c.withdraw(15000); } }.start(); new Thread() { public void run() { c.withdraw(15000); } }.start(); new Thread() { public void run() { c.withdraw(15000); } }.start(); new Thread() { public void run() { c.deposit(10000); } }.start(); } } class SharedResource { int amount = 10000; synchronized void withdraw(int amount) { System.out.println("going to withdraw..." + amount); if (this.amount < amount) { System.out.println("Less balance; waiting for deposit..."); try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } int temp = this.amount - amount; // this.amount -= amount; if (temp < 0) { System.out.println("Negative Balance"); try { wait(); } catch (Exception e) { } } this.amount = temp; System.out.println("Now total amount is: " + this.amount); System.out.println("withdraw completed..."); } synchronized void deposit(int amount) { System.out.println("going to deposit: " + amount); this.amount += amount; System.out.println("deposit completed... "); System.out.println("Now total amount is: " + this.amount); notifyAll(); } }
What is Producer & Consumer Problem in Java?
public class SampleClass { public static void main(String[] args) { Queue<Integer> buffer = new LinkedList<>(); int maxSize = 10; Thread producer = new Producer(buffer, maxSize, "PRODUCER"); Thread consumer = new Consumer(buffer, maxSize, "CONSUMER"); producer.start(); consumer.start(); } } class Producer extends Thread { private Queue<Integer> queue; private int maxSize; public Producer(Queue<Integer> queue, int maxSize, String name) { super(name); this.queue = queue; this.maxSize = maxSize; } @Override public synchronized void run() { while (true) { synchronized (queue) { while (queue.size() == maxSize) { try { System.out.println("Queue is full, " + "Producer thread waiting for " + "consumer to take something from queue"); queue.wait(); } catch (Exception ex) { ex.printStackTrace(); } } Random random = new Random(); int i = random.nextInt(); System.out.println("Producing value : " + i); queue.add(i); queue.notify(); } } } } class Consumer extends Thread { private Queue<Integer> queue; private int maxSize; public Consumer(Queue<Integer> queue, int maxSize, String name) { super(name); this.queue = queue; this.maxSize = maxSize; } @Override public void run() { while (true) { synchronized (queue) { while (queue.isEmpty()) { System.out.println("Queue is empty," + "Consumer thread is waiting" + " for producer thread to put something in queue"); try { queue.wait(); } catch (Exception ex) { ex.printStackTrace(); } } System.out.println("Consuming value : " + queue.remove()); queue.notify(); } } } }
What are the Thread Life Cycle & Multi-tasking in Java?
LIVE: Java Multithreading Deep Dive | Complete Guide + Q&A Session
Assignment/Questions for Practice:

Thanks and Regards,