简体   繁体   中英

Java threads - High cpu utilization?

I have two threads. I am invoking one (the SocketThread ) first and then from that one I am invoking another thread (the 'ProcessThread'). My issue is that, during the execution the CPU usage is 50%. It reduces to 0% when I add TimeUnit.NANOSECONDS.sleep(1) in the ProcessThread run method. Is this the right method to modify? Or any advice in general for reducing the CUP utilization.

Below is my code:

public class SocketThread extends Thread {
    private Set<Object> setSocketOutput = new HashSet<Object>(1, 1);
    private BlockingQueue<Set<Object>> bqSocketOutput;

    ProcessThread pThread;  

    @Override
    public void run() {
        pThread = new ProcessThread(bqSocketOutput);
        pThread.start();
        for(long i=0; i<= 30000; i++) {
            System.out.println("SocketThread - Testing" + i);
        }
    }

}

public class ProcessThread extends Thread {

    public ProcessThread(BlockingQueue<Set<Object>> bqTrace) {
        System.out.println("ProcessThread - Constructor");
    }

    @Override
    public void run() {
        System.out.println("ProcessThread - Exectution");
        while (true) {

            /*
            try {
                TimeUnit.NANOSECONDS.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }*/
        }
    }
}

You can "reduce the CPU utilization" by sleeping threads, but that means that you are not getting any work done on those threads (or if you are, it's getting done dramatically slower than if you just let the threads run full-out). It's like saying you can reduce fuel consumption in your car by stopping every few miles and turning the engine off.

Typically a while(true) loop being run without some sort of blocking thread synchronization (like a .Wait() , or in your situation, a BlockingQueue.take() as @Martin-James suggests) is a code smell and indicates code that should be refactored.

If your worker thread waits on the blocking queue by calling take() it should not consume CPU resources.

If its in a tight loop that does nothing (as the code in the example suggests) then of course it will consume resources. Calling sleep inside a loop as a limiter probably isn't the best idea.

You have two tight loops that will hog the CPU as long there's work to be done. Sleeping is one way to slow down your application (and decrease CPU utilization) but it's rarely, if ever, the desired result.

If you insist on sleeping, you need to increase your sleep times to be at least 20 milliseconds and tune from there. You can also look into sleeping after a batch of tasks. You'll also need a similar sleep in the SocketThread print loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM