首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >优化Java代码以实现快速响应

优化Java代码以实现快速响应
EN

Stack Overflow用户
提问于 2018-08-16 01:23:57
回答 2查看 128关注 0票数 1

我有一个多线程Java应用程序,它使用多个CPU密集型线程来收集信息。每隔几分钟就会找到一个需要由程序的另一个线程处理的结果。找到的结果被添加到一个列表中,并通知另一个相关的线程(使用Lock和Condition),之后它处理找到的信息。我需要在线程之间传递此信息的时间延迟尽可能小。使用System.currentTimeMillis()测量唤醒和通知之间的时间时,延迟通常小于5毫秒,并且通常小于或等于1毫秒。有时,延迟会更大(10-20ms)。由于毫秒是计算机的宏单位,我认为可靠地小于1ms的延迟应该是可能的,这将使我的应用程序受益。

你知道更大延迟的原因是什么吗,或者我怎么才能找到哪里去看呢?可能是垃圾收集吗?或者线程唤醒的几毫秒的变化被认为是正常的吗?

我在Linux Ubuntu虚拟专用服务器上使用Java版本1.8.0。

给出了程序设计的一个实例。运行此命令并不能正确模拟我的生产程序所观察到的延迟。“实际”程序使用了大量的内存和CPU,并且每隔几分钟只传输一次少量的信息。我试图简单地模拟这一点,但失败了。

谢谢。

import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.Condition;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;

public class Example {
    public static void main(String[] args) {
        startInfoThreads();
        startWatcherThread();
    }

    private static Lock lock = new ReentrantLock();
    private static Condition condition = lock.newCondition();
    private static List<Long> infoList = new ArrayList<>();

    private static void startWatcherThread () {
        Thread t = new Thread () {
            @Override
            public void run () {
                while (true) {
                    // Waiting for results...
                    try {
                        lock.lock();
                        while (infoList.size() == 0) {
                            try {
                                condition.await();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        long delta = System.currentTimeMillis() - infoList.remove(0);
                        if (delta > 0)
                            System.out.println("Time for waking up: " + delta);
                    } finally {
                        lock.unlock();
                    }
                    // Do something with info
                }
            }
        };
        t.start();
    }

    private static void startInfoThreads () {
        for (int i = 0; i < 14; i++) {
            Thread t = new Thread() {
                @Override
                public void run() {
                    Random r = new Random();
                    while (true) {
                        // Gather info, 'hits' about once every few minutes!
                        boolean infoRandomlyFound = r.nextInt(100) >= 99;
                        if (infoRandomlyFound) {
                            try {
                                lock.lock();
                                infoList.add(System.currentTimeMillis());
                                condition.signal();
                            } finally {
                                lock.unlock();
                            }
                        }
                    }
                }
            };
            t.start();
        }
    }
}
EN

回答 2

Stack Overflow用户

发布于 2018-08-16 01:27:55

System.currentTimeMillis()可能会受到时钟漂移的影响,通常粒度约为10ms。

要测量运行时间,您应该始终使用System.nanoTime(),因为它可以保证准确性。

票数 0
EN

Stack Overflow用户

发布于 2018-08-16 15:37:25

它可能不会加快您的进程,但使用BlockingQueue肯定会使代码更清晰。

还请注意没有信息时的Thread.sleep

final BlockingQueue<Long> queue = new ArrayBlockingQueue<>(10);

private void startWatcherThread() {
    Thread t = new Thread() {
        @Override
        public void run() {
            while (true) {
                // Waiting for results...
                try {
                    Long polled = queue.poll(1, TimeUnit.SECONDS);
                    // Do something with info
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    t.start();
}

private void startInfoThreads() {
    for (int i = 0; i < 14; i++) {
        Thread t = new Thread() {
            @Override
            public void run() {
                Random r = new Random();
                while (true) {
                    // Gather info, 'hits' about once every few minutes!
                    boolean infoRandomlyFound = r.nextInt(100) >= 99;
                    if (infoRandomlyFound) {
                        queue.put(System.currentTimeMillis());
                    } else {
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        t.start();
    }
}

private void test() {
    startInfoThreads();
    startWatcherThread();

}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51863514

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档