当前位置: 首页 > 知识库问答 >
问题:

多线程 Java 应用程序中的数据缓冲

缪兴腾
2023-03-14

我有一个多线程应用程序,它有一个生产者线程和几个消费者线程。数据存储在一个共享的线程安全集合中,当缓冲区中有足够的数据时,就刷新到数据库中。

来自爪哇文档 -

BlockingQueue<E>

一个队列,它还支持在检索元素时等待队列变为非空,并在存储元素时等待队列中的空间变为可用。

take()

检索并删除此队列的头部,如有必要,请等待元素可用。

我的问题是-

    < li >是否有另一个集合具有E[] take(int n)方法?即阻塞队列等待,直到元素可用。我想要的是,它应该等到100或200个元素可用时。 < li >或者,我是否可以使用另一种方法来解决这个问题,而无需轮询?

共有3个答案

暴招
2023-03-14

我不确定标准库中是否有类似的类具有 take(int n) 类型方法,但您应该能够包装默认的 BlockingQueue 以添加该函数而不会有太多麻烦,你不觉得吗?

另一种方案是触发一个操作,在该操作中您将元素放入集合中,您设置的阈值将触发刷新。

杜苏燕
2023-03-14

< code>drainTo方法并不完全是您想要的,但是它能满足您的目的吗?

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html#drainTo(java.util.Collection,int)

编辑

您可以使用takedrainTo的组合来实现性能稍高的批处理阻塞takemin:

public <E> void drainTo(final BlockingQueue<E> queue, final List<E> list, final int min) throws InterruptedException
{
  int drained = 0;
  do 
  {
    if (queue.size() > 0)
      drained += queue.drainTo(list, min - drained);
    else
    {
      list.add(queue.take());
      drained++;
    }
  }
  while (drained < min);
}
胡承载
2023-03-14

我认为唯一的方法是要么扩展< code>BlockingQueue的某些实现,要么使用< code>take创建某种实用方法:

public <E> void take(BlockingQueue<E> queue, List<E> to, int max) 
        throws InterruptedException {

    for (int i = 0; i < max; i++)
        to.add(queue.take());
}
 类似资料:
  • 问题内容: 在多线程应用程序中如何使用Hibernate(例如,每个客户端连接在服务器上启动它自己的线程)。 EntityManager应该仅由EntityManagerFactory创建一次,例如: 还是我必须为每个线程以及关闭EM的每个事务重新创建实体? 我的CRUD方法如下所示: 我要不要每次都跑?还是因为每个人都使用自己的缓存创建自己的EntityManager实例而使我陷入麻烦了? 问题

  • 我有一个Cordova应用程序(),我希望在其中添加离线数据高速缓存,我也想在其中预取一些数据,即使用户没有去查看通常会调用该数据的请求。 我发现的大多数缓存帖子都与缓存web资产(如实际的应用程序文件)有关,而不是通过ajax获取的数据。在我的情况下,(科尔多瓦),我已经有了所有这些,我只需要缓存数据。对于资产缓存,我看到toolbox提到了很多,并且是从服务工作者内部运行的。 工具箱可以用于此

  • 问题内容: 我最近继承了一个小型Java程序,该程序从大型数据库中获取信息,进行一些处理并生成有关该信息的详细图像。原始作者使用单个线程编写了代码,然后对其进行了修改,以使其可以使用多个线程。 他在代码中定义了一个常量; 然后,它设置用于创建映像的线程数。 我理解他的理由,即线程数不能大于可用处理器的数目,因此将其设置为可以充分发挥处理器潜力的数量。这样对吗?还是有更好的方法来充分利用处理器的潜力

  • 问题内容: 自两年以来,我一直在使用java(Servlets,JSPs)进行Web应用程序开发。在那两年中,我从不需要在任何项目中使用(明确地- 众所周知,servlet容器使用线程为不同的请求提供相同的servlet)。 但是,每当我参加Web开发人员职位(java)的面试时,就会有几个与java中的线程相关的问题。我知道Java线程的基础知识,因此回答问题不是问题。但是有时我会感到困惑,是否

  • 我将Spring缓存与CacheManager结合使用,并可在10个不同的应用程序中缓存同一表中的相同数据。实现时的假设是,我们缓存的数据是元数据,不应更改。然而,他们正在更改这些数据,缓存永远不会被清除。 现在的要求是通过2个大请求同时清除所有10个应用程序的缓存。 每当mySQL工作台上的直接INSERT语句更改表时,所有应用程序缓存都应该刷新。我使用的是Hibernate和Spring,但请

  • 那么,这种架构的瓶颈在哪里?也许推送每条带有互斥体的消息是个坏主意?