Home > Blockchain >  2 Threads taking turns printing the alphabet
2 Threads taking turns printing the alphabet

Time:10-18

I am supposed to write code for an assignment. The goal is to make 2 threads (which are objects of a class that implements runnable) take turns printing the alphabet. One of them prints upper case while the other one prints lower case. (they print only a single letter each turn, not the whole alphabet, just for clarification)

I feel like my code is pretty self-explainatory but if I am wrong here and you have questions please ask them! I appreciate any help I can get for sure!

The Code:

public class ABCPrinter implements Runnable {

    // --- Attributes ---

   private boolean bool_isUpperCase;
   public  boolean bool_Switch = true;

   // --- Constructor ---

   public ABCPrinter (boolean init_isUpperCase) {

       this.bool_isUpperCase = init_isUpperCase;

   }

    @Override
    public synchronized void run() { // custom run method

        for (char char_Counter = 'a'; char_Counter <= 'z'; char_Counter  ) { // count through the alphabet

            if (bool_isUpperCase){ // decide whether to print upper or lower case

                if(bool_Switch) {

                    System.out.println(Character.toUpperCase(char_Counter));
                    System.out.println("\n----------------------");
                    System.out.println("Message has been sent.");
                    System.out.println("-----------------------");

                    try {

                        Thread.sleep(1000);

                    } catch(Exception e) {

                        System.out.println("\nInterrupted.");

                    }

                    bool_Switch = false;
                    System.out.println("\n--------------------");
                    System.out.println("Switch has been set to false.");
                    System.out.println("-----------------------");

                    try {

                        Thread.sleep(10000);

                        notifyAll();
                        System.out.println("\n--------------------");
                        System.out.println("All threads have been notified.");
                        System.out.println("-----------------------");

                        Thread.sleep(10000);

                        wait();
                        System.out.println("\n--------------------");
                        System.out.println("Thread 1 is waiting.");
                        System.out.println("-----------------------");

                    } catch (Exception e) {

                        System.out.println("Process Interrupted.");

                    }

                } else {

                    try {

                        System.out.println("Thread 1 is waiting.");
                        wait();

                    } catch (Exception e) {

                        System.out.println("Process Interrupted.");

                    }

                }

            } else {

                if(!bool_Switch) {

                    System.out.println(Character.toUpperCase(char_Counter));
                    System.out.println("\n----------------------");
                    System.out.println("Message has been sent.");
                    System.out.println("-----------------------");

                    try {

                        Thread.sleep(1000);

                    } catch(Exception e) {

                        System.out.println("\nInterrupted.");

                    }

                    bool_Switch = true;
                    System.out.println("\n--------------------");
                    System.out.println("Switch has been set to true.");
                    System.out.println("-----------------------");

                    try {

                        Thread.sleep(1000);

                        notifyAll();
                        System.out.println("\n--------------------");
                        System.out.println("All threads have been notified.");
                        System.out.println("-----------------------");

                        Thread.sleep(1000);

                        wait();
                        System.out.println("\n--------------------");
                        System.out.println("Thread 2 is waiting.");
                        System.out.println("-----------------------");

                    } catch (Exception e) {

                        System.out.println("Process Interrupted.");

                    }

                } else {

                    try {

                        System.out.println("Thread 2 is waiting.");
                        wait();

                    } catch (Exception e) {

                        System.out.println("Process Interrupted.");

                    }

                }

            }

        }

    }

}

Here is the main method where everything is executed:

public class Main2 {

    public boolean bool_switch;

    public static void main(String[] args){

        ABCPrinter p1 = new ABCPrinter(true);
        ABCPrinter p2 = new ABCPrinter(false);
        
        Thread thr_UpperCase = new Thread(p1);
        Thread thr_LowerCase = new Thread(p2);

        thr_UpperCase.start();
        thr_LowerCase.start();

    }

}

Like I said I appreciate any help or advice for improvement. I would first and foremost love to get it to work though, been stuck at this assignment for 2 days now.

Have a good one!

CodePudding user response:

If you work with concurrencies and Threads. The class Semaphore is actually pretty helpful. I used the Producer-Consumer Pattern to solve your problem.Also keep in mind to use the join function in your Main.

Main: public class Main2 {

public static void main(String[] args) throws InterruptedException {

    ABCPrinter p1 = new ABCPrinter(true);
    ABCPrinter p2 = new ABCPrinter(false);

    final Thread thr_UpperCase = new Thread(p1);
    final Thread thr_LowerCase = new Thread(p2);



    thr_LowerCase.start();
    thr_UpperCase.start();

    thr_LowerCase.join();
    thr_UpperCase.join();

}

}

import java.util.concurrent.Semaphore;

public class ABCPrinter implements Runnable {
    private final boolean printUpperCaseBoolean;
    private static final Semaphore FREE_SEMAPHORE;
    private static final Semaphore WORK_SEMAPHORE;
    private static final Semaphore MUTEX_SEMAPHORE;

    static{
        FREE_SEMAPHORE = new Semaphore(0);
        WORK_SEMAPHORE = new Semaphore(1);
        MUTEX_SEMAPHORE = new Semaphore(2);
    }

    public ABCPrinter(final boolean printUpperCaseBoolean) {
        this.printUpperCaseBoolean = printUpperCaseBoolean;

    }


    @Override
    public void run() {
        for (char char_Counter = 'a'; char_Counter <= 'z'; char_Counter  ) { // count through the alphabet

            if(printUpperCaseBoolean){
            try{
                WORK_SEMAPHORE.acquire();
                MUTEX_SEMAPHORE.acquire();
                System.out.println(Character.toUpperCase(char_Counter));
                MUTEX_SEMAPHORE.release();
                FREE_SEMAPHORE.release();
            }
            catch (InterruptedException ex){
                ex.printStackTrace();
            }
            }else{
                try {
                    FREE_SEMAPHORE.acquire();
                    MUTEX_SEMAPHORE.acquire();
                    System.out.println(char_Counter);
                    MUTEX_SEMAPHORE.release();
                    WORK_SEMAPHORE.release();
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

The output looks like:

A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p Q q R r S s T t U u V v W w X x Y y Z z

CodePudding user response:

This new answer involves the usage of wait and notify as requested by you.The main function changed a little to include a mutex Object that is used for synchronization:

Main:

public class Main2 {

    public static void main(String[] args) throws InterruptedException {
        // Mutex object that will serve as a lock
        final Object mutex = new Object();

        ABCPrinter p1 = new ABCPrinter(mutex, true);
        ABCPrinter p2 = new ABCPrinter(mutex, false);

        final Thread thr_UpperCase = new Thread(p1);
        final Thread thr_LowerCase = new Thread(p2);


        thr_LowerCase.start();
        thr_UpperCase.start();

        thr_LowerCase.join();
        thr_UpperCase.join();

    }
}

ABC Printer:

public class ABCPrinter implements Runnable {
    private final Object mutex;
    private static char currentChar;

    private final boolean printUpperCaseBoolean;

    static {
        currentChar = 'a';
    }

        public ABCPrinter(final Object mutex, final boolean printUpperCaseBoolean) {
            this.mutex = mutex;
            this.printUpperCaseBoolean = printUpperCaseBoolean;
        }
    
    
        @Override
        public void run() {
            while (currentChar <= 'z') {
                if (printUpperCaseBoolean) {
                    try {
                        synchronized (mutex) {
                            mutex.notify();
                            System.out.println(Character.toUpperCase(currentChar));
                            currentChar  ;
                            mutex.wait();
                        }
                    }
                    catch (InterruptedException interruptedException) {
                        interruptedException.printStackTrace();
                    }
                }
                else {
                    try {
                        // Wait so that this thread can't start directly again
                        Thread.sleep(100);
                        synchronized (mutex) {
                            System.out.println(currentChar);
                            currentChar  ;
                            mutex.notify();
                        }
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

This prints: A b C d E f G h I j K l M n O p Q r S t U v W x Y z

  • Related