我一直在對我的應用程序進行一些 cpu 分析,我注意到需要大量時間的一件事是確保我每秒發(fā)送 mo 多于查詢到 web 服務的代碼。相比之下,實際查詢本身和結果處理只需要很少的時間,當然有一個 I/O 組件在等待結果,但我想做的是減少 cpu,因為應用程序有時必須在單個 cpu 機器上運行使用YourKit Profiler使用大量 cpu 的調用是 java.util.concurrent.locks.AbstractQueuedSynchronizer.aquireQueued()我的延遲方法如下 public class SearchServer { private static java.util.concurrent.locks.Lock delayLock = new ReentrantLock(); private static AtomicInteger queryQueue = new AtomicInteger(); private static AtomicLong queryDelay = new AtomicLong(); static void doDelayQuery() { delayLock.lock(); try { if(isUserCancelled()) { return; } //Ensure only send one query a second Date currentDate = new Date(); long delay = currentDate.getTime() - querySentDate.getTime(); if (delay < delayInMilliseconds) { try { long delayBy = delayInMilliseconds - delay; queryDelay.addAndGet(delayBy); Thread.sleep(delayBy); logger.info(Thread.currentThread().getName() + ":Delaying for " + delayBy + " ms"); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw new UserCancelException("User Cancelled whilst thread was delay sleeping"); } } } finally { //We set before unlocking so that if another thread enters this method before we start query we ensure they //do not skip delay just because the query that this thread has delayed for has started querySentDate = new Date(); delayLock.unlock(); } } }
1 回答

縹緲止盈
TA貢獻2041條經(jīng)驗 獲得超4個贊
好的,使用 Google Guava 庫結果非常簡單
import com.google.common.util.concurrent.RateLimiter;
public class SearchServer
{
private static RateLimiter rateLimiter = RateLimiter.create(1.0d);
static void doDelayQuery()
{
rateLimiter.acquire();
}
public doQuery()
..................
}
雖然以前的關鍵區(qū)別是我花費了上一次調用的時間,所以在兩次調用之間沒有等待整整一秒,所以為了獲得相似的吞吐量,我將 RateLmiter 更改為使用 2.0d
分析不再顯示該區(qū)域的 CPU 命中。
添加回答
舉報
0/150
提交
取消