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

标签 java multithreading

我有一个多线程 Java 应用程序,它使用多个 CPU 密集型线程来收集信息。每隔几分钟,就会发现需要由程序的另一个线程处理的结果。找到的结果被添加到列表中,并通知其他相关线程(使用锁定和条件),然后处理找到的信息。我需要将这些信息从一个线程传递到另一个线程的时间延迟尽可能小。当使用 System.currentTimeMillis() 测量唤醒和通知之间的时间时,延迟通常小于 5 毫秒,最常见的是小于或等于 1 毫秒。有时,延迟会更大(10-20ms)。由于对于计算机而言,毫秒是宏观单位,因此我认为可靠地小于 1 毫秒的延迟应该是可能的,这对我的应用程序有利。

您知道造成较大延迟的原因是什么吗?或者我如何才能找到在哪里查找?会不会是垃圾收集?或者线程唤醒的几毫秒变化是否被认为是正常的?

我在 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();
        }
    }
}

最佳答案

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

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

关于java - 优化Java代码以实现快速响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51863514/

相关文章:

java - 在 Java Web 应用程序中处理无效请求的方法?

java - 听起来是 Java 语言。错误

java - 如何在 gerrit 插件中使用 LifecycleListener?

java - 在for循环中初始化变量

java - 设置 TextView 文本时应用程序卡住

java - 我应该使用应用程序服务器吗?

java - 用于 coSTLy 请求的请求聚合器/中间层设计模式

java - 为什么没有出现僵局

c# - CancellationToken - 请求取消后注册处理程序

c# - 通过线程以一定的时间间隔执行任务一定次数