简体   繁体   English

Java 中的多个线程不遵守套接字超时?

[英]Socket timeout not respected with multiple threads in Java?

I have a java program that spawns out 4 threads.我有一个产生 4 个线程的 java 程序。 In each thread, I have multiple socket timeouts.在每个线程中,我有多个套接字超时。 However, it seems that these timeouts are not respected ie the readLine() function might block for a longer period of time.但是,似乎这些超时不受尊重,即readLine() function 可能会阻塞更长的时间。

I want the following behavior: If I set a socket timeout to 300 ms, then I want the readLine() function to return within 300 ms from when the readLine() (ie the underlying select call) was invoked, no matter what.我想要以下行为:如果我将套接字超时设置为 300 毫秒,那么我希望readLine() function 在调用readLine() (即底层 select 调用)后 300 毫秒内返回,无论如何。 I understand that the OS scheduler would be putting the threads to sleep while doing processor sharing, but is there any way in Java to force the threads to always be woken up to ensure this behavior?我知道操作系统调度程序会在进行处理器共享时使线程进入睡眠状态,但是 Java 中是否有任何方法可以强制线程始终被唤醒以确保这种行为? Or is this just not the right way to think when doing multi-threaded programming?还是在进行多线程编程时这不是正确的思考方式?

Ideally, since I am spawning out 4 threads and running on a 6-core machine, each thread should be able to get its own CPU and run in parallel, and respect the select timeout... but that's perhaps too much to expect...理想情况下,由于我产生了 4 个线程并在 6 核机器上运行,每个线程应该能够获得自己的 CPU 并并行运行,并尊重 select 超时......但这可能太期待了...... .

PS: I actually do use Thread.interrupt() to ensure that each of my threads exits within a certain time (I check the time elapsed in the master thread, and interrupt the child threads if its been too long). PS:我实际上确实使用 Thread.interrupt() 来确保我的每个线程在一定时间内退出(我检查主线程中经过的时间,如果太长则中断子线程)。 In each of my threads, I connect to a (different) server, make a request, and wait for a response.在我的每个线程中,我连接到(不同的)服务器,发出请求,然后等待响应。 I do not know how long the response will be.不知道多久会有反应。 So I keep on calling the readLine() method, till it times out with a SocketTimeoutException .所以我继续调用readLine()方法,直到它因SocketTimeoutException而超时。 I enforce a timeout of 300 ms, since I expect the server to start responding within this time.我强制执行 300 毫秒的超时,因为我希望服务器在这段时间内开始响应。 The reason I want to enforce this timeout is that the server behaves in a broadcast fashion, and sends responses to a request by a single client to all clients.我要强制执行此超时的原因是服务器以广播方式运行,并将单个客户端对请求的响应发送到所有客户端。 So if I don't have a timeout, I will keep on getting data in response to requests by some other clients.因此,如果我没有超时,我将继续获取数据以响应其他一些客户的请求。

If I really understood your problem, you can always try to invoke Thread.interrupt() in the thread that is performing the readLine() operation.如果我真的理解你的问题,你总是可以尝试在执行readLine()操作的线程中调用Thread.interrupt() As you didn't provide any code, I leave this link for you to read.由于您没有提供任何代码,因此我将此链接留给您阅读。 It's general, but it provides enough information about interrupting threads.它很笼统,但它提供了有关中断线程的足够信息。

These two links may also be of use to you: How do you kill a thread in Java?这两个链接也可能对你有用: 你如何在 Java 中杀死一个线程? and How to abort a thread in a fast and clean way in java?以及如何在 java 中以快速干净的方式中止线程? . .

Regarding your question about the OS scheduler, you should be aware that in general purpose OSes you do not have total control on the way the OS schedules tasks.关于您关于操作系统调度程序的问题,您应该知道,在通用操作系统中,您无法完全控制操作系统调度任务的方式。 For instance, in Linux the interrupts are the highest priority tasks, then there are scheduling policies that enable you to put "some" determinism on how the tasks are scheduled.例如,在 Linux 中,中断是最高优先级的任务,然后有调度策略使您能够对任务的调度方式进行“一些”确定。 In Java, you can use the setPriority() method to change the priority of the thread, but in fact it is the same as using the nice command, and still you don't get any guarantees that this thread will be scheduled ahead of other OS threads.在 Java 中,可以使用setPriority()方法更改线程的优先级,但实际上它与使用nice命令相同,但仍然无法保证该线程将优先于其他线程调度操作系统线程。

I hope this helps.我希望这有帮助。

You are making some wrong assumptions here:你在这里做了一些错误的假设:

  • that the timeout will be exactly 300ms.超时将恰好是 300 毫秒。 In fact the timeout is that will be at least 300ms.事实上,超时时间至少为 300 毫秒。
  • the OS Scheduler does not do anything (rather than schedule the java os processes) within the java threads.操作系统调度程序在 java 线程内不做任何事情(而不是调度 java 操作系统进程)。
  • having 6 core, does not mean that each one of your threads will run at separate core, it is not possible to bind thread->core at java有 6 个核心,并不意味着您的每个线程都将在单独的核心上运行,不可能在 java 处绑定线程->核心
  • for last, you consider that the jvm has only yours 4 threads running, but in fact there has more threads, by example, the garbage collector thread(s).最后,您认为 jvm 只有您的 4 个线程在运行,但实际上还有更多线程,例如垃圾收集器线程。

Asking your question: "is there any way in Java to force the threads to always be woken up to ensure this behavior? " Yes, depending how it is your code, if the thread is thread.sleep() , you can use thread.interrupt() (for readline() uses it) and handle the InterruptionException or if they are object.wait() , you can use object.notify() or object.notifyAll() .问你的问题:“Java 中是否有任何方法可以强制线程始终被唤醒以确保这种行为?”是的,取决于你的代码,如果线程是thread.sleep() ,你可以使用 thread.sleep() 。 interrupt() (用于 readline() 使用它)并处理InterruptionException或者如果它们是object.wait() ,您可以使用object.notify()object.notifyAll()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM