Reputation: 884
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
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