【问题标题】:How do I read and write to a file using threads in java?java - 如何使用java中的线程读取和写入文件?
【发布时间】:2011-06-09 18:10:32
【问题描述】:

我正在编写一个应用程序,我需要从单个文件中读取块,每个块大约是 512 字节。我也需要同时写块。

我的想法之一是 BlockReader implements RunnableBlockWriter implements RunnableBlockManager 管理读者和作者。

在我发现的大多数示例中,我看到的问题是锁定问题和潜在的死锁情况。有什么想法可以实现吗?

【问题讨论】:

  • 不按顺序写入无论如何都会损害性能。我认为具有单个工作(写入)线程的阻塞队列解决方案会提供更好的性能和更少的麻烦......
  • @extraneon 似乎这应该是一个答案而不是评论;)
  • 只是为了清楚起见 - 是并发编写需求,还是只想让数据生成线程在完成后转储他们的数据,以便他们可以继续处理一些不同的块?
  • WarmWaffles 你指定并发写,我的方案不做并发写:(
  • @extraneon 后者,加载器显然会将块加载到内存中,用户会弄乱它,然后当完成时 BlockWriter 会将块提交到文件中,然后从内存中删除块.

标签: java multithreading java-io


【解决方案1】:

我会推荐这本书 java Concurrency in Practice,在本例中为第 5.3 节(生产者-消费者模式)。

您的解决方案可能类似于:

BlockingQueue<Data> queue = 
    new  LinkedBlockingQueue<Data>(MAX_BLOCKS_IN_QUEUE_UNTIL_BLOCK );

for (int i=0; i < MAX_DATA_PRODUCERS; i++ ) {
   new Thread( new DataProducer( queue ) ).start();
}

new Thread(DataWriter( queue )).start

显然 DataProducer 和 DataWriter 是可运行的。

 class DataProducer implements Runnable {
    ...
    queue.put(data); // blocks if MAX_BLOCKS_IN_QUEUE_UNTIL_BLOCK 
                     // are waiting to be written
                     // This prevents an OutOfMemoryException
    ...
 }

 class DataConsumer implements Runnable {
   ...
   try {
       while(true) {
           writeData(queue.take()); // blocks until there is a block of data
       }
   } catch (InteruptedException e) {
       Thread.currentThread().interrupt();
   }
   ...
 }

【讨论】:

    【解决方案2】:

    您可以拥有一组锁,例如32 并使用块的索引作为哈希来确定要获得哪个锁。这样,您可以(大部分时间)进行并发读/写,并且仍然确保您不会在多个线程中读/写同一个块。

    【讨论】:

    • 我毫不怀疑这会起作用,但我真的认为同时编写具有所需搜索的单个文件并不是那么有效。我认为具有单个消费者的生产者-消费者模式会更好,但我很想听听其他意见。
    • 无论哪种方式,您都应该获得相同的性能。 P-C 模型可能是更好的设计选择。
    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    • 2015-04-10
    • 1970-01-01
    相关资源
    最近更新 更多