I'm trying to set up a timer thread that once a second increments a counter and outputs the result to the terminal.
public class SecondCounter implements Runnable
{
private volatile int counter;
private boolean active;
private Thread thread;
public SecondCounter()
{
counter = 0;
active = true;
thread = new Thread(this);
thread.start();
}
public int getCount()
{
return counter;
}
public void run()
{
while(active)
{
try {
Thread.sleep(1000);
} catch(InterruptedException ex) {ex.printStackTrace();}
synchronized(this)
{
System.out.print(++counter+" ");
try{
notifyAll();
wait();
} catch(InterruptedException ex) {ex.printStackTrace();}
}
}
}
Then, I have another method in the class called messagePrinter() that takes in an integer, creates a new thread, and monitors the main timer thread to see when a multiple of that int is on the count:
public synchronized void messagePrinter(final int x)
{
Runnable mp = new Runnable()
{
public void run()
{
while(active)
{
synchronized(this)
{
try {
while(counter%x != 0 || counter == 0 )
{
notifyAll();
wait();
}
System.out.println("\n"+x+" second message");
notifyAll();
} catch(InterruptedException ex) {ex.printStackTrace();}
}
}
}
};
new Thread(mp).start();
}
I have tried messing around with wait() and notifyAll() quite a bit but every combination I have tried results in both threads entering a wait state and causing deadlock. Or, the timer thread will hog all of the thread time and never give the messagePrinter a chance to check what the count is currently at.
Here is what the output should look like:
1 2 3
3 second message
4 5 6
3 second message
I am aware that the timer is probably not going to time to be perfectly 1 second per tick with this method, but the point of the exercise was to get some experience with passing information between threads.
Here is my main file:
public class Main2
{
public static void main(String[] args)
{
SecondCounter c = new SecondCounter();
c.messagePrinter(3);
}
}
Anyone with some threading experience care to give me some insight on where I am going wrong?
EDIT: I have converted my integer counter to an atomic integer, and I changed the messagePrinter to be synchronized on "SecondCounter.this" instead of "this". It's working now! Mostly anyway, it's printing "x second message" about thirty times a loop when there are multiple messagePrinters. I think I can fix that though.