Java多线程问题 - 消费者/生产者模式

时间:2013-07-19 09:32:40

标签: java multithreading concurrency locking java.util.concurrent

尝试解决此问题,但事实证明这很困难。

我有两个主题,一个是制作人,另一个是消费者。所有人都在不同的班级这两个线程独立运行。制作人正在汇集大约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");
}

3 个答案:

答案 0 :(得分:2)

Java生产者/消费者习语现在通常使用BlockingDeque

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

如果我理解正确,您在生产者和消费者之间没有任何通知机制。生产者将文件存储在一个文件夹中,并且消费者有一个无限循环,它读取该文件夹中的所有文件并将它们移动到其他地方。

这就是问题所在。这是我如何解决它。

生产者和消费者应共享一个BlockingQueue实例。每次生产者完成生成文件(文件完全写入共享文件夹)时,它都会将文件名添加到阻塞队列中。

消费者从队列中获取文件名。这是一个阻止操作,因此在文件名可用之前,将阻止使用者。当消费者从队列中获得文件名时,它会读取此文件(仅限此文件),并根据需要执行任何操作。

这有几个好处:

  • 没有生产者和消费者同时访问一个文件的风险
  • 您可以拥有任意数量的生产者和消费者
  • 消费者不会无休止地扫描目录
  • 你可以设置一个绑定队列,以避免产生太多文件,让消费者有机会跟上生产者的步伐。