patternjavaMinor
Decrease CPU usage in while loop
Viewed 0 times
whileloopusagecpudecrease
Problem
I've a application which runs with two threads. The main thread runs in one infinity-while-loop:
The second thread, which uses more than 50% of my CPU, must be able to stop and run again, which I asked already with this question on Stack Overflow.
The solution works perfectly, but as I already said, it uses >50% of the CPU. Here are the two loops of the solution:
```
private volatile boolean finished = true;
public void run() {
Process p;
while (true) {
// loop until the thread is finished
while (!finished) {
try {
// let every lamp shine...
p = Runtime.getRuntime().exec(onCommand + "-green");
p.waitFor();
// ... for 0.5 seconds ...
Thread.sleep(500);
// ... then turn it off again ...
p = Runtime.getRuntime().exec(offCommand + "-green");
p.waitFor();
// ... and let the next lamp shine
p = Runtime.getRuntime().exec(onCommand + "-yellow");
p.waitFor();
Thread.sleep(500);
p = Runtime.getRuntime().exec(offCommand + "-yellow");
p.waitFor();
p = Runtime.getRuntime().exec(onCommand + "-red");
p.waitFor();
Thread.sleep(500);
p = Runtime.getRuntime().exec(offCommand + "-red");
p.waitFor();
p = Runtime.getRuntime().exec(onCommand + "-blue");
p.waitFor();
Thread.sleep(500);
p = Runtime.getRuntime().exec(offCommand + "-blue");
p.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStac
while (true) {
try {
ArrayList infoList = zabbixHandler.APIRequest();
handleInfo.handleInformation(infoList);
Thread.sleep(5000);
}
}The second thread, which uses more than 50% of my CPU, must be able to stop and run again, which I asked already with this question on Stack Overflow.
The solution works perfectly, but as I already said, it uses >50% of the CPU. Here are the two loops of the solution:
```
private volatile boolean finished = true;
public void run() {
Process p;
while (true) {
// loop until the thread is finished
while (!finished) {
try {
// let every lamp shine...
p = Runtime.getRuntime().exec(onCommand + "-green");
p.waitFor();
// ... for 0.5 seconds ...
Thread.sleep(500);
// ... then turn it off again ...
p = Runtime.getRuntime().exec(offCommand + "-green");
p.waitFor();
// ... and let the next lamp shine
p = Runtime.getRuntime().exec(onCommand + "-yellow");
p.waitFor();
Thread.sleep(500);
p = Runtime.getRuntime().exec(offCommand + "-yellow");
p.waitFor();
p = Runtime.getRuntime().exec(onCommand + "-red");
p.waitFor();
Thread.sleep(500);
p = Runtime.getRuntime().exec(offCommand + "-red");
p.waitFor();
p = Runtime.getRuntime().exec(onCommand + "-blue");
p.waitFor();
Thread.sleep(500);
p = Runtime.getRuntime().exec(offCommand + "-blue");
p.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStac
Solution
don't use a busy wait but instead use a wait condition (here using the built-in monitor in Object):
I note that
I put the
To help any more I need to see what exactly happens inside that while loop.
public void run() {
while(true){
while(!finished){
// do stuff
}
try{
synchronized(this){
while(finished)
wait();//wait until notify gets called in startThread
}
}catch(InterruptedException e){}
}
}
public synchronized void startThread() {
finished = false;
notify();//wake up the wait
}I note that
finished should remain volatile. I put the
wait() in the synchronized block in a while loop to avoid the race where the thread has just tested the first while condition and is about to enter the synchronized block but startThread() then gets called; putting finished back to false and the thread waiting anyway. This can lead to the thread blocking while waiting on a notify() that never happens.To help any more I need to see what exactly happens inside that while loop.
Code Snippets
public void run() {
while(true){
while(!finished){
// do stuff
}
try{
synchronized(this){
while(finished)
wait();//wait until notify gets called in startThread
}
}catch(InterruptedException e){}
}
}
public synchronized void startThread() {
finished = false;
notify();//wake up the wait
}Context
StackExchange Code Review Q#39152, answer score: 9
Revisions (0)
No revisions yet.