首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么Java套接字不支持中断处理?

为什么Java套接字不支持中断处理?
EN

Stack Overflow用户
提问于 2018-07-30 00:50:08
回答 2查看 97关注 0票数 3

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

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

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

现在,我的问题是,我是不是遗漏了什么,有一些变通的方法,或者在中当前的体系结构,是不是每个阻塞操作一个线程?,如果是,效率不是很低吗?

EN

回答 2

Stack Overflow用户

发布于 2018-07-30 01:12:20

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

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

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

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

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

票数 1
EN

Stack Overflow用户

发布于 2018-07-30 01:53:07

如果问题是“Java的当前架构是否真的是一个线程对应一个阻塞操作”,而“阻塞操作”指的是“数据库操作”,那么答案是否定的。目前可用于Java的大多数数据库驱动程序都是基于jdbc的,并且确实是这样工作的。但也有可用的替代方案(https://spring.io/blog/2016/11/28/going-reactive-with-spring-data)和更多的替代方案( https://blogs.oracle.com/java/jdbc-next:-a-new-asynchronous-api-for-connecting-to-a-databasehttps://dzone.com/articles/spring-5-webflux-and-jdbc-to-block-or-not-to-block)。有关该功能的工作原理,请参阅How is ReactiveMongo implemented so that it is considered non-blocking?

对于jdbc,还有包装jdbc调用(Wrapping blocking I/O in project reactorSpring webflux and reading from database )和采用这种方法的项目(https://dzone.com/articles/myth-asynchronous-jdbc)的方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51582504

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档