-1

Thread 1 prints A1 A2 A3. Thread 2 prints B1 B2 B3. I want to write a program that will make sure when both threads run the output will be A1 B1 A2 B2 A3 B3. So far I have come up with below program. Please let me know how this can be simplified? Can we use less Semaphores? Can this be achieved using wait() notify()?

package com.MultiThreading.threadSerialization;

import java.util.concurrent.Semaphore;

public class ThreadSerialization {

Semaphore a1Done = new Semaphore(0);
Semaphore b1Done = new Semaphore(0);
Semaphore a2Done = new Semaphore(0);
Semaphore b2Done = new Semaphore(0);
Semaphore a3Done = new Semaphore(0);

/**
 * methodA prints : A1 A2 A3
 */
public void methodA() {

    System.out.println("A1");
    a1Done.release();       
    b1Done.acquire();
    System.out.println("A2");
    a2Done.release();
    b2Done.acquire();       
    System.out.println("A3");
    a3Done.release();

}

/**
 * methodB prints : B1 B2 B3 
 */
public void methodB() {
    a1Done.acquire();
    System.out.println("B1");
    b1Done.release();
    a2Done.acquire();
    System.out.println("B2");
    b2Done.release();
    a3Done.acquire();       
    System.out.println("B3");


}

public void createTwoThreads() throws InterruptedException{ 
    ThreadSerialization ts = new ThreadSerialization();
    Thread T1 = new Thread(() -> ts.methodA());
    Thread T2 = new Thread(() -> ts.methodB());
    T1.start();
    T2.start();
    Thread.sleep(5000);
    System.out.println("test done");
}

}

5
  • Removed try catch for readability, though it won't compile without it. Commented Jan 12, 2018 at 18:33
  • Wrong approach. Please dont put up "not compiling" code. When people tell you: "your code is doing things the wrong way" - then ask how to fix that. And then fix it. Dont just blindly remove code. People will quickly jump on you for putting up not-compiling code. Commented Jan 12, 2018 at 18:43
  • Wasn't even that unclear in the first place, that's just Java boilerplate. Commented Jan 12, 2018 at 19:09
  • 1
    To get it to compile, enclose the body of each method in one try/catch block. An interrupt is an explicit request for your thread to stop whatever it’s doing and exit gracefully. You should never ignore InterruptedExceptions and continue as if nothing happened; doing so makes your thread a rogue thread that cannot be terminated cleanly. Commented Jan 12, 2018 at 19:21
  • @xTrollxDudex It was needlessly unclear and represented code that should either throws and/or wrapped at a higher level. Java doesn't force one to write code more complicated than Java requires.. just because Java IDEs want to "autowrap" checked exceptions doesn't mean they should be blindly honored :} I would have rejected such code under a review and it's extra important on SO where code in questions is judged much more quickly.. Commented Jan 12, 2018 at 21:27

2 Answers 2

-1

You can use two semaphore if you ensure that will only one thread executing methodA and another thread for methodB. When you print A1, you give T2 the posibility to print B1. Then it will need to wait for A2 to be printed to continue

  Semaphore aPrintDone = new Semaphore(0);
  Semaphore bPrintDone= new Semaphore(0);

/**
 * methodA prints : A1 A2 A3
 */
 public void methodA() {
     try {
         System.out.println("A1");
         aPrintDone.release();
         bPrintDone.acquire();
         System.out.println("A2");
         aPrintDone.release();
         bPrintDone.acquire();
         System.out.println("A3");
         aPrintDone.release();
    }catch (InterruptedException e1) {
         e1.printStackTrace();
    }
  }

  /**
   * methodB prints : B1 B2 B3 
  */
  public void methodB() {
    try {
        aPrintDone.acquire();
        System.out.println("B1");
        bPrintDone.release();
        aPrintDone.acquire();
        System.out.println("B2");
        bPrintDone.release();
        System.out.println("B3");
    }catch (InterruptedException e1) {
        e1.printStackTrace();
    }
}

This problem could also be resolved using wait() and notify(). Consider that wait() means that the thread will be waiting until a certain condition is met (in this case the B printing, for T1; and the A printing for thread T2). So when the System.out.println is done, it could notify() the other thread to start printing. I prefer the semaphore resolution, but it´s ok to solve it using those methods.

Sign up to request clarification or add additional context in comments.

2 Comments

Great. This is working and number of Semaphores also reduced. Can you comment on if this can be done using wait-notify as well?
@AmolBinwade I updated my answer to cover the wait-notify question.
-1

To answer the wait-notify question: Yes, it is possible. It even works with only one lock-object. But the code is neither very readable nor "secure". The code requires, that methodA() is executed before methodB(), otherwise the program will deadlock.

public class Synchronization {

    synchronized public void methodA() {
        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("A1");
        this.notify();

        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("A2");
        this.notify();

        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("A3");
        this.notify();
    }

    synchronized public void methodB() {
        this.notify();

        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("B1");
        this.notify();

        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("B2");
        this.notify();

        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("B3");
    }

    public static void main(String... args) throws InterruptedException {
        Synchronization ts = new Synchronization();
        Thread t1 = new Thread(ts::methodA);
        Thread t2 = new Thread(ts::methodB);

        t1.start(); // If you switch those lines,
        t2.start(); // the program will deadlock.

        t1.join();
        t2.join();
        System.out.println("test done");
    }
}

5 Comments

If methodA executes first, the program will stuck because T1 will wait forever.
@AmolBinwade the first wait() in methodA() is released by the immediate notify() in methodB(). Can you please specify at which wait() you have seen a deadlock in method1()?
Right..i missed that...this should work...will give it a try and confirm. Thanks.
.But the sequence t1.start() before t2.start() doesn't guarantee that methodA will start execution before methodB. Its upto the scheduler which thread it will start executing first. Right?
That is true. this is why I explicitly said in my answer that methodA() has to be called before methodB(). You can enforcde the order through, e.g., a CountDownLatch.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.