User27854
User27854

Reputation: 884

Issues in communication between threads

I am trying to work out a problem described below.

Write a program that prints message from the start of execution, with another thread that prints a message for every fifteenth message. Have the message-printing thread be notified by the message-printing thread as each message is printed by. Add another thread that prints a different message every seventh message without modifying the message-printing thread.

I have tried the following. can any one guide me as how do I call a particular thread in the program.

This class is used for

public class Message{
    String message; 
    volatile boolean flag=true;

    synchronized void printMessage(String message){
        int count=16;


        for(int i=0;true;){
            i++;

            if(i%15==0 || i%7==0){
                try {
                    wait();
                } catch (InterruptedException e) {

                    e.printStackTrace();
                }               
            }

            System.out.println(i +" "+message);
        notify();           
            }           

    }

synchronized void printMessageFifteen(String message){          

    System.out.println(message);
    notify();   

    try {
        wait();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }                       

}

synchronized void printMessageSeven(String message){            

    System.out.println(message);
    notify();   

    try {
        wait();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
            e.printStackTrace();
        }                       

    }



}

Threads that prints out the message in a continuous manner:

public class ContinousMessageThread extends Thread{

    Message messageObject;

    ContinousMessageThread(Message messageObject){
        this.messageObject=messageObject;
        new Thread(this,"seconds").start();
    }

    @Override
    public void run() {

        messageObject.printMessage(this.messageObject.message);
    }

}

Thread that prints out the message for every fifteen seconds:

public class FifteenSecondsMessageThread extends Thread{

    Message messageObject;

    public FifteenSecondsMessageThread(Message messageObject) {
        this.messageObject=messageObject;       
        new Thread(this,"seconds").start();

    }

    @Override
    public void run() {
        while(true){
        messageObject.printMessageFifteen("Fifteen Seconds over");
        }
    }

}

Thread that prints out message for every seven seconds

public class SevenSecondsMessageThread extends Thread {
    Message messageObject;


    public SevenSecondsMessageThread(Message messageObject) {
        this.messageObject=messageObject;       
        new Thread(this,"seconds").start();

    }

    @Override
    public void run() {
        while(true){
            messageObject.printMessageSeven("Seven Seconds over");
        }   
    }

}

Main class where all the threads are started..

public class MainClass {
public static void main(String[] args) {
    Object sevenSecond= new Object();
    Object fifteenSecond= new Object();


    Message messageObject= new Message();
    messageObject.message="seconds";



    ContinousMessageThread continousMessageThreadObject= new ContinousMessageThread(messageObject);
    SevenSecondsMessageThread secondsMessageThreadObject = new SevenSecondsMessageThread(messageObject);
    FifteenSecondsMessageThread fifteenSecondsMessageThreadObject=new FifteenSecondsMessageThread(messageObject); 

}

Output That I am getting :

    1 seconds
    2 seconds
    3 seconds
    4 seconds
    5 seconds
    6 seconds
    Seven Seconds over
    7 seconds
    8 seconds
    9 seconds
    10 seconds
    11 seconds
    12 seconds
    13 seconds
    Seven Seconds over
    14 seconds
    Seven Seconds over
    15 seconds
    16 seconds
    17 seconds
    18 seconds
    19 seconds
    20 seconds
    Seven Seconds over
    21 seconds
    22 seconds
    23 seconds
    24 seconds
    25 seconds
    26 seconds
    27 seconds
    Seven Seconds over
    Fifteen Seconds over
    Seven Seconds over
    28 seconds
    29 seconds
    Seven Seconds over
    Fifteen Seconds over
    30 seconds
    31 seconds
    32 seconds
    33 seconds
    34 seconds
    Fifteen Seconds over
    Seven Seconds over

Expected result is

    1 seconds
    2 seconds
    3 seconds
    4 seconds
    5 seconds
    6 seconds
    Seven Seconds over
    7 seconds
    8 seconds
    9 seconds
    10 seconds
    11 seconds
    12 seconds
    13 seconds
    Seven Seconds over
    14 seconds
    Fifteen Seconds over
    15 seconds
    16 seconds
    17 seconds
    18 seconds
    19 seconds
    20 seconds
    Seven Seconds over
    21 seconds
    22 seconds
    23 seconds
    24 seconds
    25 seconds
    26 seconds
    27 seconds
    Seven Seconds over
    28 seconds
    29 seconds
    Fifteen Seconds over
    30 seconds
    31 seconds
    32 seconds
    33 seconds
    34 seconds
    Seven Seconds over

Note:

The program works perfectly fine (on expected lines) when only SevenSecondMessageThread and ContiniousMessageThread or FifteenSecondMessageThread and ContiniousMessageThread are called. But it fails when All the threads are called. I am not able to understand why this is happening and how can I avoid this?

Upvotes: 0

Views: 66

Answers (1)

Andrea Iacono
Andrea Iacono

Reputation: 802

To obtain the desired behaviour, you could think in terms of objects to be synchronized. In this case, I defined two Object (sevenSecond and fifteenSecond) and I make synchronize the continuous thread on these two objects, so that we can define exactly which thread start or stop.

Here's a modified version of your code that implements the main idea of having a continuous thread that from time to time is interrupted by the other two:

    public static void main(String[] args){

        Object sevenSecond= new Object();
        Object fifteenSecond= new Object();

        Message messageObject= new Message();
        messageObject.message="seconds";

        ContinousMessageThread continousMessageThreadObject= new ContinousMessageThread(messageObject);
        SevenSecondsMessageThread secondsMessageThreadObject = new SevenSecondsMessageThread(messageObject);
        FifteenSecondsMessageThread fifteenSecondsMessageThreadObject=new FifteenSecondsMessageThread(messageObject);
    }


    static class Message{
        String message;
        Object sevenLock = new Object();
        Object fifteenLock = new Object();

        void printMessage(String message) {

            try {
                for(int i=0; true; i++){
                    if (i % 7 == 0) {
                        synchronized (sevenLock) {
                            sevenLock.notify();
                            System.out.println(i + " " + message);
                            sevenLock.wait();
                        }
                    }
                    else if (i % 15 == 0) {
                        synchronized (fifteenLock) {
                            fifteenLock.notify();
                            System.out.println(i + " " + message);
                            fifteenLock.wait();
                        }
                    }
                    else {
                        System.out.println(i + " " + message);
                        System.out.flush();
                    }
                    if (i == 50) System.exit(-1);  // stops after a few iterations
                }
            }
            catch(InterruptedException e) {
                e.printStackTrace();
            }

        }

        void printMessageFifteen(String message) {
            try {
                synchronized (fifteenLock) {
                    System.out.println(message);
                    fifteenLock.notify();
                    fifteenLock.wait();
                }
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        synchronized void printMessageSeven(String message) {
            try {
                synchronized (sevenLock) {
                    System.out.println(message);
                    sevenLock.notify();
                    sevenLock.wait();
                }
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class ContinousMessageThread extends Thread {

        Message messageObject;

        ContinousMessageThread(Message messageObject){
            this.messageObject=messageObject;
            new Thread(this,"seconds").start();
        }

        @Override
        public void run() {
            messageObject.printMessage(this.messageObject.message);
        }

    }


    static class FifteenSecondsMessageThread extends Thread{

        Message messageObject;

        public FifteenSecondsMessageThread(Message messageObject) {
            this.messageObject=messageObject;
            new Thread(this,"seconds").start();

        }

        @Override
        public void run() {
            while(true){
                messageObject.printMessageFifteen("Fifteen Seconds over");
            }
        }

    }

    static class SevenSecondsMessageThread extends Thread {
        Message messageObject;


        public SevenSecondsMessageThread(Message messageObject) {
            this.messageObject=messageObject;
            new Thread(this,"seconds").start();

        }

        @Override
        public void run() {
            while(true){
                messageObject.printMessageSeven("Seven Seconds over");
            }
        }

    }

Note that, as in your version, the first time the two threads (7 and 15) output their message is not related to the continuous thread (they can appear everywhere between 0 and 7 or 15); from the second on, they have the desired behaviour.

Upvotes: 2

Related Questions