【问题标题】:Concurrent Processing of csv for multiple users多用户同时处理 csv
【发布时间】:2013-04-12 14:28:06
【问题描述】:

我有一个场景,我必须为用户处理文件夹中的 CSV 文件,并在处理后将它们存储到数据库中。我们每个用户有 5 种类型的提要。 任何用户都可以发送该文件夹中的任何提要,任何时间进行处理,需要遵循以下规则:

  • 不能同时处理同一客户的同一类型的提要,这意味着必须始终阻止同时处理时间。
  • 不允许跨“x”个以上的客户端进行并发处理
  • 不允许同一客户端同时处理超过“y”个文件

实现这一目标的好方法是什么?

【问题讨论】:

  • so... 例如,一个文件的名称为 FEED1_CLIENT1?
  • 是的 FEED_CLIENT_TIMESTAMP.csv

标签: java multithreading concurrency throttling concurrent-programming


【解决方案1】:

第一个限制可以用AtomicBoolean 的映射来实现。这可能不需要是 ConcurrentHashMap,因为您不会在初始化后更改地图的键。完成后不要忘记将提要的值重置为 false。

checkAndProcessFeed(Feed feed, Map<String, AtomicBoolean> map) {
    while(!map.get(feed.type).compareAndSet(false, true)) // assuming the AtomicBooleans were initialized to false
        Thread.sleep(500);
    }
    process(feed); // at this point map.get(feed.type).get() == true
    map.get(feed.type).set(false); // reset the AtomicBoolean to false
}

另外两个限制可以用AtomicInteger来实现,用于维护客户端和每个客户端文件的计数;处理完成时递减,并用 compare-and-set 递增以启动新的客户端/文件。

final int maxClient = 5;
AtomicInteger clientCount = new AtomicInteger(0);
ConcurrentLinkedQueue<Client> queue = new ConcurrentLinkedQueue<>(); // hold waiting clients
while(true) {
    int temp = clientCount.intValue();
    if(!queue.isEmpty() && clientCount.compareAndSet(temp, temp + 1) { // thread-safe increment 
        process(clients.poll()); // don't forget to decrement the clientCount when the processing finishes
    } else Thread.sleep(500);
}

【讨论】:

  • 谢谢 Zim,看起来很有希望。但是,如果有文件进来,我们必须同时为多个客户端处理一件事。您能否还指导一下该逻辑的外观。这是节流还是线程池?
  • 你会为此使用类似 ThreadPoolExecutor 的东西;上述代码中的process(clients.poll()) 将变为threadPoolExecutor.execute(new Processor(clients.poll()),其中Processor 实现Runnable,其run 方法实现客户端处理逻辑。
  • 还有一个转折点,我们不希望在任何情况下都同时处理相同类型的提要以避免任何数据库锁定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 2020-07-06
  • 2014-05-03
  • 2020-03-01
  • 1970-01-01
相关资源
最近更新 更多