2012-10-10 44 views
0

我有可以在散文描述如下高性能的环境问题:Java资源池线程问题

我有一个外部的Java API,它使一个FPGA卡,上面有64对资源的调用。我需要一种机制来安全地在应用程序中的数百个线程之间共享这些资源的子集。每个资源应被视为不是线程安全的。

所以我需要一个ResourcePool和方法update(),然后调用resource.update()。

我认为这是一个相当常见的习惯用语,但我很难将自己的头脑融入到Java概念中。我想说在一个ResourcePool中有4个资源。我应该猜测每个人都应该活在自己的Thread中(因此需要一个线程池)。

我将如何实现这一点,以便我可以记录一个错误,并继续进行时,所有4资源都在使用?

希望这是有道理的!

+0

所以'update'方法只是从池中选取任何资源并更新它?你为什么认为每个资源都需要它自己的线程? –

+0

@MarkoTopolnik资源是硬件相关的,不能被认为是线程安全的,但我需要说100个线程与这些资源中的4个进行通信。通常,这些资源在系统中为每个线程分配1个资源。然而,我们把这个插入的Java应用程序有数百个线程。 – easytiger

+0

因此,您需要一个由四个对象组成的池,每个对象都绑定到其线程和其硬件资源。就客户而言,资源与线程相关并不重要;只是它们是一些可以在任何时候只通过一个线程获取的资源。这与您的资源是TCP连接完全相同。 –

回答

1

对于BlockingQueue来说,它对于生产者 - 消费者模式非常有用,您必须在userd之后更新或添加此资源,但是资源的初始化可能性较差。而且它是一个阻塞队列,如果你想在池空或者满时处理一些信息,Queue就可以。

对于锁定,如果这些资源被初始化并且没有改变之后,对这些资源添加锁定效果会更好。

这是我的意见。

3

我会将代表每个资源的对象放入LinkedBlockingQueue中。

要获取资源,您可以根据需要轮询(),remove()或take()。

要返回资源,您可以添加它。

+0

这很有趣......如果我删除了一个元素,然后在理论完成时将其放回原状,那么当我尝试从空队列中取出异常时,可能会发现异常。那么ConcurrentLinkedQueue会不会更好呢? – easytiger

+0

您可以随时删除元素并将其返回,但它会被添加到队列的末尾。如果队列为空,则poll()返回'null',remove()会产生一个异常,并且take()阻止等待一个元素。 CLQ没有take()。 –

2

只要每个线程只需要一个资源,就可以按照@Peter的建议使用LinkedBlockingQueue来池化资源。如果多个线程需要多于一个的线程,那么在一些线程获得一些资源的简单情况下可能会出现问题,但对于其中任何一个线程都不足以进行 - 死锁。

您可以使用两个由一个锁保护的队列。资源实例的一个“池”队列,等待获取资源的线程实例的一个“等待”队列。线程类/ s的方法返回当前正在等待的资源数量。

任何需要资源的线程都会获取锁并首先检查池队列计数。如果有足够的资源,则将其出列并退出锁定。如果没有足够的时间,它会排队等待队列,退出锁定并等待。

任何可释放其资源的线程都会获取该锁。如果等待队列为空,则它将资源释放回池中,释放锁并退出。如果等待队列不是空的,它会对其进行迭代,从而构建一组等待线程,可以使用等待释放的资源和剩余池中的资源总和来做好准备。然后它应用某种算法来决定哪些等待线程可以准备好。如果没有,它只会将资源释放回池并退出锁定。如果有的话,它会将这些线程加载资源,通知它/它们,释放锁并退出。

0

由于基本上可以将某些东西视为有限数量的通用资源,因此可以应用任何通用资源池库。谷歌返回pool4j作为第一击,这可能是你所需要的。它基于java.util.Stack。或者你可以推出你自己的解决方案。