为什么Java套接字没有';不支持中断处理?

为什么Java套接字没有';不支持中断处理?,java,Java,我一直在思考为什么JDBC只是阻塞操作,为什么我不能为假设的事件处理程序onResultSetArrived(ResultSetRS)设置一些侦听器。为什么我必须为每个JDBC查询阻塞一个线程 过了一段时间,我深入研究了Java套接字(我想JDBC是在它们之上构建的),并意识到也没有任何事件处理。提供非阻塞读取的唯一选项是通过available()方法,但这是非常低效的,因为它必须在循环中定期检查 据我所知,中断是PC机的基本问题。它从硬件一直到操作系统。在Java中,它可以通过从套接字读取值实

我一直在思考为什么JDBC只是阻塞操作,为什么我不能为假设的事件处理程序onResultSetArrived(ResultSetRS)设置一些侦听器。为什么我必须为每个JDBC查询阻塞一个线程

过了一段时间,我深入研究了Java套接字(我想JDBC是在它们之上构建的),并意识到也没有任何事件处理。提供非阻塞读取的唯一选项是通过available()方法,但这是非常低效的,因为它必须在循环中定期检查

据我所知,中断是PC机的基本问题。它从硬件一直到操作系统。在Java中,它可以通过从套接字读取值实现为事件驱动方法


现在,我的问题是我是否遗漏了一些东西,并且存在一些解决方法,或者Java中的当前体系结构确实是每个阻塞操作一个线程?如果是,它不是效率很低吗?

在Java中,可以有很多线程。线程一直在做自己的事情,直到它被阻塞在某个地方(通常是在互斥锁或I/O操作上)。当然,这不会阻止其他线程

多线程应用程序的基本场景是,在等待阻塞线程时使用多个线程会导致太多的等待。这里“太多”的定义完全取决于您,但一般来说,这就是如何通过更好地利用资源来实现更好的性能

然而,Java中线程的工作方式存在一些限制。如果不是所有线程都被阻塞在Java“外部”的某个地方,例如OS调用或外部(本机)库中,那么大多数线程都被阻塞。理论上,如果本机代码阻塞线程,Java对此无能为力。通常,除非本机代码有bug,否则这不应该是问题

所以,在阻塞JDBC响应的情况下,您将创建一个新线程,该线程将在第一个线程等待数据库完成时执行其他工作。或者,您可以创建一个线程,只用于执行JDBC。除了操作系统施加的限制外,您可以完全按照自己的意愿(使用侦听器等)进行设置。所以这是可能的,但它可能不是由JDBC驱动程序提供的。核心Java中已经有很多基础设施,您可能会发现它们很有用(线程池、工作线程、同步集合)。但与任何多线程一样,您需要非常小心地同时访问来自不同线程的数据


自Java7以来,还支持非阻塞I/O(NIO)。这几乎就是你所描述的。I/O被卸载到操作系统,因此您的操作会立即返回,并且在操作完成时会收到回调。但是,并非所有库都支持NIO。对于我的工作,我从来没有理由使用它,因为我总是可以用我的线程实现相同的东西,至少同样好。

如果问题是“Java中当前的体系结构是否真的是每个阻塞操作一个线程”,那么“阻塞操作”是指“数据库操作”那么答案是否定的。目前大多数Java可用的数据库驱动程序都是基于jdbc的,并以这种方式工作。但是,还有可用的替代方案()和更多( , ). 有关其工作原理,请参见


对于jdbc,还有一些方法可以包装jdbc调用(,)和采用这种方法的项目()

据我所知,一个线程意味着立即消耗1MB内存(在32位上是512kb)。因此,如果您一次有1000个请求,并且每个请求将以异步方式运行,消耗另外6个线程,那么即使这些线程由于等待某些阻塞操作而处于空闲状态,也会消耗6000MB的RAM。您可能只需要1个线程就可以处理这个请求,但是您有6000个线程。我不是线程方面的专家,但是性能呢?在这么多线程之间切换是必须的。当然,切换线程会带来一些开销,但无论如何这是不可避免的。一般规则是使用尽可能少的线程。在JDBC的情况下,拥有多于几个线程不太可能带来任何额外的性能改进。最好的方法是创建一个工作池和从池中获取工作的线程池。如果您正确地实现了这些异步机制,那么它们工作得非常好?如果一个对DB的请求需要200毫秒,因为DB在另一台服务器上,并且有一些延迟,那么您需要很多线程,并且大部分时间都处于阻塞状态。我认为没有任何借口去玩Java。当前的架构只是过时了,仅此而已。Oracle中有一些ADBA movenet应该提供JDBC的异步变体,但现在是2018年,它还没有完成!!!我想我还不够清楚。您希望将线程的数量与有用的工作相匹配,而不是更少,而不是更多。但是这里还有很多事情要考虑。简而言之,我看到Java中存在很多架构限制,但我不会说这是其中之一。你可以自己实现一个非常有效的解决方案——因此限制是你缺乏知识,而不是Java方面的知识。你是对的,我缺乏知识,但我非常清楚,无论有人开发什么解决方案,它仍然是一个解决方案,并且始终只是JDBC中缺乏异步的Java的一个变通方法。“Java中当前的体系结构实际上是一个阻塞操作一个线程”——对于阻塞I/O,是的。然而,ProjectLowe将光纤和延续技术引入Java,这将使其更加高效:)