Programs using Mutli-Threading

Below is a Java program that creates two threads: one for displaying all odd numbers between 1 and 100, and another for displaying all even numbers between 1 and 100.

class OddNumbersThread extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 100; i += 2) {
            System.out.println("Odd: " + i);
            try {
                Thread.sleep(100); // Optional: To slow down the output for better visualization
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class EvenNumbersThread extends Thread {
    @Override
    public void run() {
        for (int i = 2; i <= 100; i += 2) {
            System.out.println("Even: " + i);
            try {
                Thread.sleep(100); // Optional: To slow down the output for better visualization
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Main {
    public static void main(String[] args) {
        OddNumbersThread oddThread = new OddNumbersThread();
        EvenNumbersThread evenThread = new EvenNumbersThread();

        oddThread.start();
        evenThread.start();

        try {
            oddThread.join();
            evenThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Explanation
  1. OddNumbersThread Class:

    • Extends Thread and overrides the run method.
    • The run method contains a loop that prints all odd numbers between 1 and 100.
    • Optionally, Thread.sleep(100) is used to slow down the output for better visualization.
  2. EvenNumbersThread Class:

    • Extends Thread and overrides the run method.
    • The run method contains a loop that prints all even numbers between 1 and 100.
    • Optionally, Thread.sleep(100) is used to slow down the output for better visualization.
  3. Main Class:

    • Creates instances of OddNumbersThread and EvenNumbersThread.
    • Starts both threads using the start method.
    • Waits for both threads to complete using the join method.

This program creates and runs two separate threads, one for printing odd numbers and the other for printing even numbers between 1 and 100. The optional Thread.sleep(100) calls are included to make the output easier to follow by introducing a short delay between prints.

Write a Java program that implements a multi-threaded program which has three threads.First thread generates a random integer every 1 second. If the value is even, second thread computes the square of the number and prints. If the value is odd the third thread will print the value of cube of the number.

import java.util.Random;
class SharedData {
    private int number;
    private boolean processed = true; // Indicates whether the number has been processed

    public synchronized int getNumber() {
        return number;
    }

    public synchronized void setNumber(int number) {
        this.number = number;
        this.processed = false; // Reset the flag when a new number is set
    }

    public synchronized boolean isProcessed() {
        return processed;
    }

    public synchronized void setProcessed(boolean processed) {
        this.processed = processed;
    }
}


class NumberGenerator extends Thread {
    private SharedData sharedData;

    public NumberGenerator(SharedData sharedData) {
        this.sharedData = sharedData;
    }

    @Override
    public void run() {
        Random random = new Random();
        while (true) {
            int number = random.nextInt(100); // Generate a random integer
            System.out.println("Generated number: " + number);
            synchronized (sharedData) {
                sharedData.setNumber(number);
                sharedData.notifyAll(); // Notify all waiting threads
            }

            try {
                Thread.sleep(1000); // Sleep for 1 second
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class EvenNumberProcessor extends Thread {
    private SharedData sharedData;

    public EvenNumberProcessor(SharedData sharedData) {
        this.sharedData = sharedData;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (sharedData) {
                while (sharedData.isProcessed() || sharedData.getNumber() % 2 != 0) {
                    try {
                        sharedData.wait(); // Wait until there is an unprocessed even number
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                int number = sharedData.getNumber();
                int square = number * number;
                System.out.println("Square of " + number + " is " + square);
                sharedData.setProcessed(true); // Mark the number as processed
                sharedData.notifyAll(); // Notify all waiting threads
            }
        }
    }
}
class OddNumberProcessor extends Thread {
    private SharedData sharedData;

    public OddNumberProcessor(SharedData sharedData) {
        this.sharedData = sharedData;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (sharedData) {
                while (sharedData.isProcessed() || sharedData.getNumber() % 2 == 0) {
                    try {
                        sharedData.wait(); // Wait until there is an unprocessed odd number
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                int number = sharedData.getNumber();
                int cube = number * number * number;
                System.out.println("Cube of " + number + " is " + cube);
                sharedData.setProcessed(true); // Mark the number as processed
                sharedData.notifyAll(); // Notify all waiting threads
            }
        }
    }
}
public class Main {
    public static void main(String[] args) {
        SharedData sharedData = new SharedData();

        NumberGenerator numberGenerator = new NumberGenerator(sharedData);
        EvenNumberProcessor evenNumberProcessor = new EvenNumberProcessor(sharedData);
        OddNumberProcessor oddNumberProcessor = new OddNumberProcessor(sharedData);

        numberGenerator.start();
        evenNumberProcessor.start();
        oddNumberProcessor.start();
    }
}



Explanation of Each Class

  1. SharedData Class:

    • Purpose: This class holds the shared integer and a flag to indicate whether the number has been processed by either the EvenNumberProcessor or the OddNumberProcessor.
    • Attributes:
      • private int number: The shared number to be processed by the threads.
      • private boolean processed: A flag indicating if the current number has been processed.
    • Methods:
      • public synchronized int getNumber(): Returns the current number.
      • public synchronized void setNumber(int number): Sets a new number and resets the processed flag to false.
      • public synchronized boolean isProcessed(): Returns the value of the processed flag.
      • public synchronized void setProcessed(boolean processed): Sets the processed flag.
  2. NumberGenerator Class:

    • Purpose: This thread generates a random integer every second and updates the shared data.
    • Constructor:
      • public NumberGenerator(SharedData sharedData): Takes a SharedData object as a parameter and stores it.
    • run Method:
      • Generates a random integer between 0 and 99.
      • Sets the generated number in the SharedData object.
      • Calls notifyAll to wake up all waiting threads after setting the new number.
      • Sleeps for 1 second before generating the next number.
  3. EvenNumberProcessor Class:

    • Purpose: This thread processes even numbers by computing and printing their square.
    • Constructor:
      • public EvenNumberProcessor(SharedData sharedData): Takes a SharedData object as a parameter and stores it.
    • run Method:
      • Continuously checks if there is an unprocessed even number.
      • If the number is even and unprocessed, it calculates the square of the number, prints it, sets the processed flag to true, and calls notifyAll to wake up other waiting threads.
      • If the number is odd or already processed, it waits for a new number.
  4. OddNumberProcessor Class:

    • Purpose: This thread processes odd numbers by computing and printing their cube.
    • Constructor:
      • public OddNumberProcessor(SharedData sharedData): Takes a SharedData object as a parameter and stores it.
    • run Method:
      • Continuously checks if there is an unprocessed odd number.
      • If the number is odd and unprocessed, it calculates the cube of the number, prints it, sets the processed flag to true, and calls notifyAll to wake up other waiting threads.
      • If the number is even or already processed, it waits for a new number.
  5. Main Class:

    • Purpose: This class initializes the shared data and starts all three threads.
    • main Method:
      • Creates an instance of SharedData.
      • Creates instances of NumberGenerator, EvenNumberProcessor, and OddNumberProcessor, passing the shared data object to each.
      • Starts all three threads.

Program Flow
  1. The NumberGenerator thread starts and generates a random number every second.
  2. Each time a new number is generated, it is stored in the SharedData object, and the processed flag is reset to false.
  3. The NumberGenerator thread calls notifyAll to wake up all waiting threads (EvenNumberProcessor and OddNumberProcessor).
  4. The EvenNumberProcessor thread checks if the number is even and unprocessed:
    • If true, it calculates and prints the square of the number, sets the processed flag to true, and calls notifyAll.
    • If false, it waits for a new number.
  5. The OddNumberProcessor thread checks if the number is odd and unprocessed:
    • If true, it calculates and prints the cube of the number, sets the processed flag to true, and calls notifyAll.
    • If false, it waits for a new number.
  6. This cycle continues indefinitely, with each number being processed only once by the appropriate thread.

Synchronization and Coordination
  • Synchronized Methods: The SharedData class methods are synchronized to ensure thread-safe access to the shared number and the processed flag.
  • Wait and NotifyAll: The threads use wait and notifyAll to coordinate their actions. When a thread sets a new number, it calls notifyAll to wake up other threads waiting on the SharedData object. The EvenNumberProcessor and OddNumberProcessor threads wait if they find that the number is already processed or not relevant to their computation (i.e., odd number for the even processor and vice versa).

This approach ensures that each number generated by the NumberGenerator thread is processed exactly once by the appropriate thread, either computing its square (if even) or its cube (if odd).

 

Comments

Popular posts from this blog

KTU OOP LAB JAVA CSL 203 BTech CS S3 - Dr Binu V P

Syllabus and Practice Questions KTU OOPS Lab Java CSL 203

String Problems