我怎样才能让这个 Java 延迟 web 服务调用代码使用更少 cpu?

How can I make this Java delay webservice call code use less cpu?

我一直在对我的应用程序进行一些 cpu 分析,我注意到需要花费大量时间的事情之一是确保我每秒向 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();
            }

        }
    }

好的,使用 Google Guava Library 结果出奇的简单

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()
     ..................
}

尽管之前的主要区别是我占用了上一次调用的时间,所以在调用之间没有等待整整一秒,所以为了获得类似的吞吐量,我将 RateLmiter 更改为使用 2.0d

分析不再显示 cpu 命中该区域。