我有两个线程。我首先调用一个(SocketThread
),然后从该线程调用另一个线程("ProcessThread")。我的问题是,在执行过程中,CPU使用率为50%。当我在ProcessThread run
方法中添加TimeUnit.NANOSECONDS.sleep(1)
时,它会降低到0%。这是正确的修改方法吗?或者任何关于降低CUP利用率的一般建议。
以下是我的代码:
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();
}*/
}
}
}
您可以通过睡眠线程来"降低CPU利用率",但这意味着您不会在这些线程上完成任何工作(或者,如果您完成了,则完成的速度要比让线程完全运行时慢得多)。这就像说你可以通过每隔几英里停车并关闭发动机来减少汽车的油耗
通常,在没有某种阻塞线程同步的情况下运行的while(true)
循环(如.Wait()
,或者在您的情况下,如@MartinJames所建议的BlockingQueue.take()
)是一种代码气味,指示应该重构的代码。
如果您的工作线程通过调用take()在阻塞队列上等待,它不应该消耗CPU资源。
如果它处于一个什么都不做的紧密循环中(如示例中的代码所示),那么它当然会消耗资源。将睡眠循环称为限制器可能不是最好的主意。
您有两个紧密的循环,只要有工作要做,就会占用CPU。睡眠是降低应用程序速度(并降低CPU利用率)的一种方法,但它很少达到预期效果。
如果你坚持睡觉,你需要将睡眠时间增加到至少20毫秒,并从那时开始调整。你也可以考虑在完成一批任务后睡觉。在SocketThread打印循环中,您也需要类似的睡眠。