1

已尝试解决此问题,但证明很困难。

我有两个线程,一个是生产者,另一个是消费者。都在不同的班级。两个线程独立运行。生产者正在汇集大约 8-12 个文件夹用于输入。然后它同时翻译所有文件,并将其放置在一个名为“readyToLoad”的共享文件夹中。一旦生产者线程完成,消费者线程现在进入“readyToLoad”文件夹并开始处理翻译后的文档。

现在的问题是,当消费者处理翻译文件时,它不允许生产者将更多翻译文件放入“readyToLoad”文件夹。

我的问题是,如何防止消费者锁定“readyToLoad”文件夹?我该如何处理这种情况?

为长文本道歉,但我觉得这将有助于理解我在哪里遇到问题。谢谢大家的帮助。

更新:添加了消费者代码(在加载过程中执行加载并锁定文件的代码)

public class LoadManager {
protected static final Logger logger = KCLogger.getLogger();
 ArrayList<Loader> threads = new ArrayList<Loader>();
 KCBLConfig config;
 private static final ExecutorService service = Executors.newFixedThreadPool(10);
 public LoadManager(KCBLConfig config) {
    this.config = config;
 }

public void start() throws Exception {
    logger.log(Level.INFO, "Starting loading threads.");
    try {
        TreeMap<String, ConnectionHandler> connectionHandlers = config.getConnectionHandlers();
        Iterator i = connectionHandlers.keySet().iterator();
        while (i.hasNext()) {

            ConnectionHandler connectionHandler = connectionHandlers.get((String) i.next());

            for (LoadFolder loadFolder : connectionHandler.getKcXMLFolders()) {
               Loader loader = new Loader(loadFolder.getId(), loadFolder, config.getConnectionHandlers());
               Thread loaderThread = new Thread(loader);
                loaderThread.start();   
               //service.submit(loader);
              // service.shutdown();
               //service.awaitTermination(1, TimeUnit.MILLISECONDS);
                threads.add(loader);
            }
        }
    } catch (Exception e) {
        logger.log(Level.SEVERE, "There was an error starting the loaders. Stopping all loader threads.", e);
        this.stop();
        throw e;
    }
    logger.log(Level.INFO, "All loader threads created. There are " + threads.size() + " loader threads");
}
4

3 回答 3

2

Java 生产者/消费者习惯用法通常使用BlockingDequenow。

我会为生产者和消费者提供单独的文件夹。为什么要承担这种复杂性?

于 2013-07-19T09:34:04.710 回答
0

If I understand correctly, you don't have any notification mechanism between the producer and the consumer. The producer stores files in a folder, and the consumer has an infinit loop which reads all the files from this folder and moves them somewhere else.

That's the problem. Here's how I would solve it.

The producer(s) and consumer(s) should all share a single BlockingQueue instance. Each time a producer has finished producing a file (the file is completely written to the shared folder), it adds the name of the file to the blocking queue.

The consumer(s) take file names from the queue. This is a blocking operation, so the consumer is blocked until a file name is available. When a consumer has got a file name from the queue, it reads this file (and this file only), and does whatever he wants with it.

This has several advantages:

  • no risk of having one file being accessed by a producer and a consumer at the same time
  • you can have as many producers and consumers you want
  • the consumers don't scan the directory for nothing endlessly
  • you can set a bound to the queue to avoid producing too many files, and let the chance for consumers to keep up with the pace of the producers.
于 2013-07-19T10:26:58.407 回答
0

您可以Monitor在 Java http://en.wikipedia.org/wiki/Monitor_(synchronization)中使用这些synchronized方法。

于 2013-07-19T10:00:43.240 回答