Java 中的多线程不考虑套接字超时?

发布于 2024-11-05 04:03:15 字数 703 浏览 0 评论 0原文

我有一个 java 程序,它产生 4 个线程。在每个线程中,我都有多个套接字超时。然而,似乎这些超时没有得到遵守,即 readLine() 函数可能会阻塞更长的时间。

我想要以下行为:如果我将套接字超时设置为 300 毫秒,那么我希望 readLine() 函数在 readLine() (无论如何,都会调用底层的 select 调用。我知道操作系统调度程序在进行处理器共享时会将线程置于睡眠状态,但是Java中有没有办法强制线程始终被唤醒以确保这种行为?或者这在进行多线程编程时不是正确的思考方式?

理想情况下,由于我生成 4 个线程并在 6 核计算机上运行,​​因此每个线程应该能够获得自己的 CPU 并并行运行,并遵守选择超时...但这可能太令人期待了.. PS :

我实际上使用 Thread.interrupt() 来确保每个线程在一定时间内退出(我检查主线程中经过的时间,如果时间太长则中断子线程)。在每个线程中,我连接到(不同的)服务器,发出请求,然后等待响应。不知道要多久才能得到回复。因此,我继续调用 readLine() 方法,直到超时并出现 SocketTimeoutException。我强制执行 300 毫秒的超时,因为我希望服务器在这段时间内开始响应。我想强制执行此超时的原因是服务器以广播方式运行,并将单个客户端对请求的响应发送给所有客户端。因此,如果我没有超时,我将继续获取数据以响应其他一些客户端的请求。

I have a java program that spawns out 4 threads. In each thread, I have multiple socket timeouts. However, it seems that these timeouts are not respected i.e. the readLine() function might block for a longer period of time.

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() (i.e. the underlying select call) was invoked, no matter what. 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? 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 ...

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). 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. I enforce a timeout of 300 ms, since I expect the server to start responding within this time. 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

-残月青衣踏尘吟 2024-11-12 04:03:15

如果我真的理解你的问题,你总是可以尝试在执行 readLine() 操作的线程中调用 Thread.interrupt() 。由于您没有提供任何代码,因此我保留此链接 供您阅读。它很通用,但它提供了有关中断线程的足够信息。

这两个链接可能对您也有用: How do you Kill a Java 中的线程?如何在java中快速干净地中止线程?

关于您有关操作系统调度程序的问题,您应该意识到,在通用操作系统中,您无法完全控制操作系统调度任务的方式。例如,在 Linux 中,中断是最高优先级的任务,然后有调度策略,使您能够对任务的调度方式施加“某种”确定性。在Java中,你可以使用setPriority()方法来改变线程的优先级,但实际上它和使用nice命令是一样的,而且你还是不知道。无法保证该线程将排在其他操作系统线程之前。

我希望这有帮助。

If I really understood your problem, you can always try to invoke Thread.interrupt() in the thread that is performing the readLine() operation. 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? and How to abort a thread in a fast and clean way in 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. 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.

I hope this helps.

衣神在巴黎 2024-11-12 04:03:15

您在这里做出了一些错误的假设:

  • 超时恰好是 300 毫秒。事实上,超时至少为 300 毫秒。
  • 操作系统调度程序在 java 线程中不执行任何操作(而不是调度 java 操作系统进程)。
  • 不可能将线程->核心绑定在java上
  • 拥有6个核心,并不意味着你的每个线程都将在单独的核心上运行,最后 ,你认为jvm只有你的4个线程在运行,但事实上有更多线程,例如垃圾收集器线程。

问你的问题:“Java中有什么方法可以强制线程始终被唤醒以确保这种行为吗?”
是的,取决于您的代码,如果线程是thread.sleep(),您可以使用thread.interrupt()(对于readline()使用它)并处理InterruptionException< /em>或者如果它们是object.wait(),则可以使用object.notify()object.notifyAll()

You are making some wrong assumptions here:

  • that the timeout will be exactly 300ms. In fact the timeout is that will be at least 300ms.
  • the OS Scheduler does not do anything (rather than schedule the java os processes) within the java threads.
  • 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
  • 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).

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().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文