0

我在高性能环境中遇到问题,可以用散文描述如下:

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

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

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

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

希望这是有道理的!

4

4 回答 4

3

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

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

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

于 2012-10-10T15:43:10.303 回答
2

正如@Peter 所建议的那样,使用 LinkedBlockingQueue 来池化资源是可以的,只要每个线程只需要一个资源。如果多个线程需要多个线程,那么在简单情况下可能会出现问题,即多个线程已经获取了一些资源,但不足以让它们中的任何一个继续进行 - 死锁。

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

任何需要资源的线程都会获取锁并首先检查池队列计数。如果有足够的资源,它会将它们出列并退出锁。如果不够,它会将自己排入等待队列,退出锁并等待..

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

于 2012-10-10T16:14:23.723 回答
1

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

对于锁,如果这些资源被初始化后没有变化,给这些资源加锁比较好。

这是我的意见。

于 2012-10-11T03:36:37.977 回答
0

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

于 2012-10-11T13:24:45.610 回答