栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

多线程海量文件读取

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程海量文件读取

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

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

让我们再举一个例子,它与您的例子相似,但实际上可以提供一些好处:假设我想在庞大的单词列表中搜索某个单词的出现(该列表甚至可能来自磁盘文件,但是像我一样表示,由单个线程读取)。假设我可以像您的示例中那样使用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 tasksSearchTask 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 taskThread t1 = new Thread(task1);Thread t2 = new Thread(task2);Thread t3 = new Thread(task3);// start threadst1.start();t2.start();t3.start();// wait for threads to finisht1.join();t2.join();t3.join();// collect resultsint counter = 0;counter += task1.getCounter();counter += task2.getCounter();counter += task3.getCounter();

这应该很好地工作。请注意,在实际情况下,您将构建更通用的分区方案。您也可以使用

ExecutorService
and实现,
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 tasksList<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 tasksExecutorService exec = Executors.newFixedThreadPool(3);List<Future> results = exec.invokeAll(tasks);// wait for tasks to finish and collect resultsint counter = 0;for(Future f: results) {    counter += f.get();}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/414109.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号