Java code - threads blocking each other

I am new to multithreading. I am trying to write a program where I have two threads. One thread prints an odd number and then drops the monitor lock using wait () and similarly another thread prints an even number and gives up the lock after printing the number I have 4 classes

  • Odd.java (print odd numbers between 1-100)
  • Even.java (print an even number between 1-100)
  • SomeMaths.java (has logic to print odd and even numbers)
  • OEApp.java (Main class that starts threads)

Problem. My code works as expected most of the time if it prints numbers from 1 to 100 in order. And the thread in turn. But I noticed there is a bug. Sometimes the even thread gets the scheduled first and exits below the output

2    **********
1    ###############################

      

After that nothing is printed. It looks like a dead end situation. I can't figure out why. Please help me understand this.

public class SomeMaths {

    public synchronized void printOdd(){
        for( int i=1;i<=100;i++){
            if(i%2 !=0) {
                System.out.println(i + "       ###############################");
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            notify();
        }
    }

    public synchronized void printEven(){
        for(int i=1;i<=100;i++){
            if(i%2 ==0){
                System.out.println(i +"    **********");
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            notify();
        }
    }
  }

      

public class Odd implements Runnable {

    SomeMaths sm;

    public Odd(SomeMaths sm){
        this.sm = sm;
    }
    @Override
    public void run(){
       sm.printOdd();
    }
}

      

public class Even extends Thread {

    SomeMaths sm;

    public Even(SomeMaths sm){
        this.sm = sm;
    }

    @Override
    public void run(){
        sm.printEven();
    }
}

      

public class OEApp {

    public static void main(String[] args) {

        SomeMaths sm = new SomeMaths();

        Thread odd = new Thread(new Odd(sm));
        Thread even = new Thread(new Even(sm));

        odd.start();
        even.start();

        try {
            odd.join();
            even.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

      

+3


source to share


2 answers


I believe it works like this:



  • An even thread starts, 1 is odd, so it raises a notification (without notifying anyone) and then 2 even prints a message and waits

  • Odd thread starts, 1 is odd, so it prints a message and waits

  • There, no one can trigger a notification so that both threads wait forever

+6


source


What is your purpose of using the sync keyword ?
This can only assure you that your function will not run multiple times at the same time.

I'm guessing you want one thread to notify the other? It is right?
But what if the notify call is called before waiting ?

Do you know that you can use a debugger to watch each thread and therefore know where each thread is stuck?

Please note that after calling start, you cannot know which thread will have cpu time.



Also, you are trying to synchronize two threads (using the notify / wait mecanism method), but there are other mecanisms that will be proven easier (e.g. semaphore : each thread has its own semaphore , acquiring its own semaphore and freeing the other semaphore ; initialize each semaphore to 1 and it will run smoothly).

PS:

-2


source







All Articles