java - java中的高分辨率定时器

标签 java multithreading networking concurrency

我想在 Java 中模拟 TCP。

为此,我有多个线程,例如每个 TCP 连接的发送方和接收方线程。

我的问题是,我想暂停(如 Thread.sleep())线程数微秒的时间间隔。这样我就可以模拟流量控制,发送方线程将在发送下一个数据包之前阻塞几微秒,同时 CPU 可以被接收和数据处理线程使用。但是我找不到任何执行微秒或纳秒分辨率的 sleep() 或 wait() 的方法。如何在 Java 中以微秒级或纳秒级分辨率阻止(暂停)线程?

我找到了 System.nanoTime() 方法,但是没有方法可以在指定的微秒或纳秒内阻塞线程。如果有任何这样的方法,请告诉我。 System.nanoTime() 仅给出以纳秒为单位的相对时间间隔。

我可以使用 System.nanoTime() 在使用忙循环的线程中执行纳秒级延迟,但这会浪费 CPU,而这些 CPU 本可以用于接收数据线程或处理线程。

另一个令人困惑的问题:

通过上网冲浪,我发现在 Windows 系统中 Thread.sleep() 或 wait() 方法阻塞至少指定的毫秒数或 10 毫秒的倍数,以较小者为准,没有线程中断。但是当我运行示例时,我发现了非常不同的结果。就像线程 hibernate 时间少于指定的毫秒数。有些线程给我 100 微秒的 sleep 时间。是不是时间测量有误? System.nanoTime() 不是那么准确吗?请参阅下面的示例,其中我得到了非常不同的结果。线程优先级也没有给出预期的结果。

public class MyClass {
    public static void main(String args []){
        Runnable r = new Runnable() {
            public void run() {
                long s = System.nanoTime();
                //Thread.yield();  // Try for yield, need to check - in how much time high priority thread will be scheduled back after yielding
                try{
                    Thread.sleep(1);
                }catch(Exception e){

                }
                long e = System.nanoTime() - s;
                System.out.println(Thread.currentThread().getName()+e);
            }
        };

        Thread t1 = new Thread(r, "Thread T1: ");
        t1.setPriority(Thread.MAX_PRIORITY);
        t1.start();

        Thread t2 = new Thread(r, "Thread T2: ");
        t2.setPriority(Thread.MIN_PRIORITY);
        t2.start();

        Thread t3 = new Thread(r, "Thread T3: ");
        t3.setPriority(Thread.NORM_PRIORITY);
        t3.start();

        Thread t4 = new Thread(r, "Thread T4: ");
        t4.setPriority(Thread.MAX_PRIORITY);
        t4.start();

        long s = System.nanoTime();
        try{
            Thread.sleep(1);
        }catch(Exception e){

        }
        long e = System.nanoTime() - s;
        System.out.println("Main: "+e);
    }
}

在我的 Intel Core i5,2.53 GHz 系统中,我在多次运行中得到类似于下面的输出。 *这篇文章中没有打印下面输出中的换行符,我已经从控制台复制了输出,但是它在我的控制台中给了我换行符,这不是问题。

线程 T1:736682 线程 T3:700212 线程 T2:478559 主营:548257 线程 T4:458299

第二次运行 -

线程 T3:27555 线程 T2:139799 线程 T1:152361 主营:93199 线程 T4:29986

第三次运行 -

线程 T4:724525 线程 T2:1050319 主营:752486 线程 T1:941316 线程 T3:1000883

第四轮 -

线程 T1:174243 线程 T2:166543 线程 T3:1005745 主营:1023170 线程 T4:915787

在上面的运行中,我得到微秒阻塞。 :O

请指导我。

为长篇文章道歉。感谢您阅读整篇文章。

最佳答案

请注意 Thread.sleep(timeout)保证 Thread 将 hibernate 至少 超时毫秒(取决于底层系统的精度),但它可能会 hibernate 更长时间。

有一个Thread.sleep(millis, nanos) ,但精度也不是很好。正如 @TimBender 在下面指出的那样,在 OpenJDK 6-b14 中,它甚至通过舍入和调用 Thread.sleep(millis) 来实现这一点。因此,可以肯定地说,在任何 Java 实现中,您都不能依赖它来 hibernate 一个确切的时间间隔。

关于java - java中的高分辨率定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13129538/

相关文章:

c++ - 列出所有网络连接,然后管理一个

python - 在单独的线程中运行 SimpleXMLRPCServer 并关闭

multithreading - Perl:从后台线程关闭 open2 句柄

java - 在Java中将数值转换为日期

java - 错误 Android Volley 意外响应代码 400

java - 为什么 CachedThreadPool 会满负荷但不启动第二个线程,有什么原因吗?

java - 每个客户端一个线程。可行吗?

azure - 如何在azure VM上公开HTTP端口

java - LinkedHashSet 实现 LRU

java - 将变量标记为 final 如何允许内部类访问它们?