为了账号安全,请及时绑定邮箱和手机立即绑定

如何使这个 Java 延迟 web 服务调用代码使用更少的 cpu?

如何使这个 Java 延迟 web 服务调用代码使用更少的 cpu?

侃侃尔雅 2022-07-20 10:05:35
我一直在对我的应用程序进行一些 cpu 分析,我注意到需要大量时间的一件事是确保我每秒发送 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条经验 获得超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()

     ..................

}

虽然以前的关键区别是我花费了上一次调用的时间,所以在两次调用之间没有等待整整一秒,所以为了获得相似的吞吐量,我将 RateLmiter 更改为使用 2.0d


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


查看完整回答
反对 回复 2022-07-20
  • 1 回答
  • 0 关注
  • 90 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信