I have the following situation. I have an application that runs mostly on one thread. It has grown large, so I would like to run a watchdog thread that gets called whenever the main thread changes into a different block of code / method / class so I can see there is “movement” in the code. If the watchdog gets called by the same area for more than a second or a few, it shall set a volatile boolean that the main thread reads at the next checkpoint and terminate / restart.
Now the problem is getting either of the threads to run somewhat at the same time. As soon as the main thread is running, it will not let the watchdog timer count properly. I was therefore thinking of yielding every time it calls the watchdog (so it could calculate time passed and set the value) but to no avail. Using Thread.sleep(1) instead of Thread.yield() works. But I don’t want to have several areas of code just wasting calculation time, I am sure I am not doing it the way it is meant to be used.
Here a very simple example of how I would use Thread.yield(). I do not understand why the Threads here will not switch (they do, after a “long” and largely unpredictable time). Please give me an advice on how to make this simple example output ONE and TWO after each other. Like written before, if I switch yield() with sleep(1), it will work just like I’d need it to (in spite of waiting senselessly).
Runnable run1 = new Runnable(){
public void run(){
while(true){
System.out.println("ONE");
Thread.yield();
}
}
};
Runnable run2 = new Runnable(){
public void run(){
while(true){
System.out.println("TWO");
Thread.yield();
}
}
};
Thread tr1 = new Thread(run1);
Thread tr2 = new Thread(run2);
tr1.start();
tr2.start();
I think this is more about the difference between ~1000
printlncalls in a second (when you usesleep(1)) and many, many more without the sleep. I think theThreadis actually yielding but it may be that it is on a multiple processor box so the yield is effectively a no-op.So what you are seeing is purely a race condition high volume blast to
System.out. If you ran this for a minute with the results going to a file I think you’d see a similar number of"ONE"and"TWO"messages in the output. Even if you removed theyield()you would see this behavior.I just ran a quick trial with your code sending the output to
/tmp/x. The program withyield()ran for 5 seconds, generated 1.9m/483k lines, with the outputsort | uniq -cof:This means that each thread is generating upwards of 40,000 lines/second. Then I removed the
yield()statements and I got just about the same results with different counts of lines like you’d expect with the race conditions — but the same order of magnitude.