2012-05-31 27 views
1

我正在开发一个独立的java应用程序,它通过网络从大约1000个测量设备收集数据并将数据保存到数据库。 由于设备输出速度和/或网络速度较慢,数据收集每个设备可能需要几分钟的时间。数据收集必须在一定的时间窗口内进行,所以我需要并行工作。Java并发/联网方法

我的方法是为每个测量设备创建一个线程,将数据放入队列中,并在队列的另一端有一个或多个其他线程转换并保留数据。

这是一种可行的方法吗?现代机器能够处理多线程和网络连接吗?这是多大的可扩展性,在什么时候我需要在几台机器上工作?

如果你能给我关于你会推荐的concurreny类的指针(即什么样的队列,ThreadPoolExecutor等 - 我还没有使用java.util.concurrent,书本在邮件中) 。

有没有更好的方法?

UPDATE:

感谢您的答案至今,这里是一些你要求的更多信息。

我从设备收到的数据是小于1kb的文件形式。在一次传输过程中,我可能会得到类似于25.000个文件的内容,尽管通常它少得多。

数据转换不是cpu密集型的,基本上解析文件并将其转换为java数据类型(该文件包含像unsigned char和unix时间戳这样的c数据类型)以及CRC计算。我创建了一个包含一个文件内容的对象,我使用JPA将其保存到数据库中(我想我也可以在这种情况下使用普通的JDBC)。测量文件中没有顺序,因为它们包含设备的序列号和时间戳。

在稍后的时间点,当满足某些条件时,我将不得不添加某种警报,但这不应该是cpu密集型的。

从答案到目前为止我收集的网络连接和线程数应该不成问题。

我唯一想知道的是关于队列的方法。另一种方法是让数据收集线程也调用DAO方法来保存文件。我想我必须尽可能使DAO线程安全,但我认为有几个线程也可以完成这项工作,因为大部分时间将用于传输网络数据。

另外我会研究异步I/O和一些提供它的框架。再次

谢谢,我会在稍后选择一个答案,也许我会得到一些更多的输入:)

+0

“放在一个队列中的数据” - 你要摆在那排队什么样的数据? –

回答

1

在默认设置下,如果您在64位Linux上运行,Oracle jdk(默认线程堆栈大小在此平台上为1Mb),您最终将为线程堆栈使用大约1Gb的内存。我认为OpenJDK也是一样。不包括由os分配的缓冲区。 。 。

如果这是太多你的要求,你可能想看看http://netty.io。这个框架使用java下的nio(可以配置使用bio,btw)。这样,你只需要几个thread,做实际的IO(执行读取/写入OPS对一个给定的TCP连接)。你的商业逻辑(更新数据库,计算一些测量数据)应该被卸载到一个单独的线程池中。 Netty也包括对此的支持。

如果你想使用每个连接1个线程(每个测量装置?),那么有可能是从没有在尚未线程完成实际业务工作的另一个好处一大堆。我假设每个设备有一个线程,因为您说设备速度较慢和/或网络速度较慢。如果你使用多线程,那么瓶颈(网络和设备)将不会被消除(人们可以预期相反)。

并发类一般:java.util.concurrent中*是的,无论是竖起大拇指

1

对于一个现代化的操作系统和硬件,处理1000 +更改线程和网络连接不应该是一个问题。真正的问题是你收集了多少数据,以及这些转换有多复杂 - 这可能会决定一台机器可以处理多少数据。

0

IMO,你应该考虑从设备收集数据的异步IO。一旦你已经从一个套接字读的东西,这张贴到队列(并发或以其他方式),并有螺纹阅读过此队列的项目池。

唯一的问题是为设备维护自然顺序的数据,也许您可​​以为每个设备设置一个队列,并向线程池连接的队列发布某种令牌,以指示哪个设备已准备好进行处理。然后一个线程将处理该设备的队列,并做必要的工作,如果它需要更多的数据,它不具有从设备队列消费,它可以在那里留下它,直到所有的数据已经到达。