Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
488 views
in Technique[技术] by (71.8m points)

使用ThreadPoolExecutor并用Threed.sleep模拟任务执行,实际sleep实际不准确且远长于设置时间

问题描述

我自己创建了一个ThreadPoolExecutor,并且在执行任务时使用Threed.sleep(2000)模拟任务执行的时间消耗,但是在实测当中Threed.sleep(2000)的等待时间除了开始有些是2s以外,后续等待时间越来越长,甚至超过一分钟,不清楚是为什么。

示例代码

 AtomicInteger curPage = new AtomicInteger(-1);
 int limit = 10;
 // 分页查询数据
 long totalCount = dataRepository.count();
 // 获取总页数
 int totalPage = (int) Math.ceil(totalCount / limit);
 AtomicInteger remainPage = new AtomicInteger(totalPage);
 // 获取当前时间戳
 Long now = LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond();
 // 创建用于处理任务的线程池
 ExecutorService executors = new ThreadPoolExecutor(20, 20, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
 // 循环处理每页数据
 while (remainPage.get() > 0) {
    executors.execute(() -> {
        // 进入循环,总页数减一,当前页翻页,查询数据
        remainPage.decrementAndGet();
        curPage.incrementAndGet();
        
        System.out.println("curPage: " + curPage.get() + " --- " + "remainPage: " + remainPage.get());
        try {
            long time = System.currentTimeMillis();
            Thread.sleep(2000);
            System.out.println("释放!!!!---- time: " + (System.currentTimeMillis() - time));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
 }

实际结果

image.png

疑问

查询了下没找到相关描述,非常疑惑这个地方为什么差距会这么大。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Thread.sleep(2000);只是定时唤醒,至于线程什么时候抢到cpu资源是个问题。
remainPage比较大时,while大量执行抢占cpu,decrementAndGet()incrementAndGet()并发也是大量抢占cpu,sleep()唤醒之后,都在等上面的decrementAndGet、incrementAndGet


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...