当前位置: 首页 > 面试题库 >

多线程海量文件读取

应和光
2023-03-14
问题内容

我仍在全神贯注地了解Java中并发的工作方式。我知道(如果您订购的是OO Java 5并发模型)则分别实现a TaskCallablewith
run()或or call()方法,并且它应该使您尽可能多地并行实现该方法。

但是我仍然不了解Java并发编程的内在知识:

  • 一个是怎样Taskrun()方法分配给执行工作的同时适量的?

作为一个具体的例子,如果我有一个I / O绑定的readMobyDick()方法,该方法将从本地系统上的文件中读取Herman Melville的
Moby Dick 的全部内容到内存中。且仅说我希望此readMobyDick()方法是并发的,并由3个线程处理,其中:

  • 线程#1将书的前1/3读入内存
  • 线程#2将书的第二个1/3读入内存
  • 线程#3将书的最后1/3读入内存

我是否需要将Moby
Dick分成三个文件,并将每个文件传递给他们自己的任务,还是只readMobyDick()从实现的run()方法内部进行调用II,并且(以某种方式)Executor知道如何在线程之间分解工作。

我是一个非常视觉化的学习者,因此非常感谢使用正确方法实现此目的的任何代码示例!谢谢!


问题答案:

您可能偶然地选择了并行活动的绝对最差示例

实际上,从单个机械磁盘并行读取要比使用单个线程读取速度慢,因为实际上您是在每个线程轮流运行时将机械头弹跳到磁盘的不同部分。最好将其保留为单线程活动。

让我们再举一个例子,它与您的例子相似,但实际上可以提供一些好处:假设我想在庞大的单词列表中搜索某个单词的出现(该列表甚至可能来自磁盘文件,但是像我一样表示,由单个线程读取)。假设我可以像您的示例中那样使用3个线程,每个线程都在巨大单词列表的1/3上进行搜索,并保留一个本地计数器来显示搜索到的单词出现的次数。

在这种情况下,您希望将列表分为三部分,将每个部分传递给一个不同的对象,该对象的类型实现Runnable并在该run方法中实现搜索。

运行时本身不知道如何进行分区或类似的操作,您必须自行指定。还有许多其他的分区策略,每种策略都有自己的优点和缺点,但是我们现在可以坚持使用静态分区。

让我们看一些代码:

class SearchTask implements Runnable {
     private int localCounter = 0;
     private int start; // start index of search
     private int end;
     private List<String> words;
     private String token;

     public SearchTask(int start, int end, List<String> words, String token) {
         this.start = start;
         this.end = end;
         this.words = words;
         this.token = token;
     }

     public void run() {
         for(int i = start; i < end; i++) {
              if(words.get(i).equals(token)) localCounter++;
         }
     }

     public int getCounter() { return localCounter; }
}

// meanwhile in main :)

List<String> words = new ArrayList<String>();
// populate words 
// let's assume you have 30000 words

// create tasks
SearchTask task1 = new SearchTask(0, 10000, words, "John");
SearchTask task2 = new SearchTask(10000, 20000, words, "John");
SearchTask task3 = new SearchTask(20000, 30000, words, "John");

// create threads for each task
Thread t1 = new Thread(task1);
Thread t2 = new Thread(task2);
Thread t3 = new Thread(task3);

// start threads
t1.start();
t2.start();
t3.start();

// wait for threads to finish
t1.join();
t2.join();
t3.join();

// collect results
int counter = 0;
counter += task1.getCounter();
counter += task2.getCounter();
counter += task3.getCounter();

这应该很好地工作。请注意,在实际情况下,您将构建更通用的分区方案。您也可以使用ExecutorServiceand实现,Callable而不是Runnable如果要返回结果。

因此,一个使用更高级构造的替代示例:

class SearchTask implements Callable<Integer> {
     private int localCounter = 0;
     private int start; // start index of search
     private int end;
     private List<String> words;
     private String token;

     public SearchTask(int start, int end, List<String> words, String token) {
         this.start = start;
         this.end = end;
         this.words = words;
         this.token = token;
     }

     public Integer call() {
         for(int i = start; i < end; i++) {
              if(words.get(i).equals(token)) localCounter++;
         }
         return localCounter;
     }        
}

// meanwhile in main :)

List<String> words = new ArrayList<String>();
// populate words 
// let's assume you have 30000 words

// create tasks
List<Callable> tasks = new ArrayList<Callable>();
tasks.add(new SearchTask(0, 10000, words, "John"));
tasks.add(new SearchTask(10000, 20000, words, "John"));
tasks.add(new SearchTask(20000, 30000, words, "John"));

// create thread pool and start tasks
ExecutorService exec = Executors.newFixedThreadPool(3);
List<Future> results = exec.invokeAll(tasks);

// wait for tasks to finish and collect results
int counter = 0;
for(Future f: results) {
    counter += f.get();
}


 类似资料:
  • 本文向大家介绍python多线程分块读取文件,包括了python多线程分块读取文件的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了python多线程分块读取文件的具体代码,供大家参考,具体内容如下 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 我正在研究哲学家进餐问题,n位哲学家轮流思考和进餐。我想有一个版本,哲学家们会按照id的顺序进食:0,1,2,3,4。。。,但是我的线程一直被阻塞。我的线程从调用PhilosopherThread开始。 我想把哲学家们整理好有点麻烦。我只能在线程堵塞之前吃前2个线程。 编辑:据我所知,我这样做是对的。我首先锁定互斥锁,然后检查pindex是否是当前线程id,如果不是,线程将等待,直到pindex等

  • 问题内容: 我目前有一个程序可以在单线程模式下读取文件(非常大)并创建搜索索引,但是在单线程环境下建立索引的时间太长。 现在,我正在尝试使其在多线程模式下工作,但不确定实现该目标的最佳方法。 我的主程序创建一个缓冲的读取器,并将实例传递给线程,并且线程使用缓冲的读取器实例读取文件。 我认为这并不符合预期,而是每个线程一次又一次地读取同一行。 有没有一种方法可以使线程仅读取其他线程未读取的行?我需要

  • 我必须以2KB的块读取文件,并在这些块上执行一些操作。现在我实际上陷入困境的地方是,当数据需要线程安全时。根据我在在线教程和 StackOverflow 答案中看到的内容,我们定义了一个工作线程,并重写了它的运行方法。run 方法使用队列中的数据,我们将其作为参数传递,并且包含实际数据。但是要用数据加载该队列,我必须按顺序遍历文件,这消除了并行性。我希望多个线程以并行方式读取文件。因此,我必须仅在

  • 本文向大家介绍python多线程同步之文件读写控制,包括了python多线程同步之文件读写控制的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了python多线程同步之文件读写控制的具体代码,供大家参考,具体内容如下 1、实现文件读写的文件ltz_schedule_times.py 2.1、不加锁对文件进行多线程读写。file_lock.py 得到结果: 文件写入结果: 以上结果可以看

  • 问题内容: 关于我的上一个问题,我发布了: 我必须阅读几个非常大的txt文件,并且必须使用多个线程或一个线程来执行此操作,具体取决于用户输入。 假设我有一个主要方法来获取用户输入,并且用户请求一个线程,并希望为该线程处理20个txt文件。我将如何完成?请注意,以下内容不是我的代码或其设置,而是“想法”的含义。 例: 因此,总而言之,我将如何用一个线程完成此任务? 有20个线程? 用户建议使用thr