我想用ExecutorService
及其函数invokeAll
用Java编写程序。我的问题是:invokeAll
函数是否同时解决任务?我的意思是,如果我有两个处理器,那么同时会有两名工人?因为我不能让它正确地缩放。这需要在同一时间完成的问题,如果我给newFixedThreadPool(2)
或1Java ExecutorService - 缩放
List<Future<PartialSolution>> list = new ArrayList<Future<PartialSolution>>();
Collection<Callable<PartialSolution>> tasks = new ArrayList<Callable<PartialSolution>>();
for(PartialSolution ps : wp)
{
tasks.add(new Map(ps, keyWords));
}
list = executor.invokeAll(tasks);
Map
是实现Callable
和wp
是部分解决方案的一个载体,保存在不同时代的一些信息类的类。
它为什么不缩放?可能是什么问题呢?
这是PartialSolution的代码:
import java.util.HashMap;
import java.util.Vector;
public class PartialSolution
{
public String fileName;//the name of a file
public int b, e;//the index of begin and end of the fragment from the file
public String info;//the fragment
public HashMap<String, Word> hm;//here i retain the informations
public HashMap<String, Vector<Word>> hmt;//this i use for the final reduce
public PartialSolution(String name, int b, int e, String i, boolean ok)
{
this.fileName = name;
this.b = b;
this.e = e;
this.info = i;
hm = new HashMap<String, Word>();
if(ok == true)
{
hmt = new HashMap<String, Vector<Word>>();
}
else
{
hmt = null;
}
}
}
的这对地图的代码:
public class Map implements Callable<PartialSolution>
{
private PartialSolution ps;
private Vector<String> keyWords;
public Map(PartialSolution p, Vector<String> kw)
{
this.ps = p;
this.keyWords = kw;
}
@Override
public PartialSolution call() throws Exception
{
String[] st = this.ps.info.split("\\n");
for(int j = 0 ; j < st.length ; j++)
{
for(int i = 0 ; i < keyWords.size() ; i++)
{
if(keyWords.elementAt(i).charAt(0) != '\'')
{
int k = 0;
int index = 0;
int count = 0;
while((index = st[j].indexOf(keyWords.elementAt(i), k)) != -1)
{
k = index + keyWords.elementAt(i).length();
count++;
}
if(count != 0)
{
Word wr = this.ps.hm.get(keyWords.elementAt(i));
if(wr != null)
{
Word nw = new Word(ps.fileName);
nw.nrap = wr.nrap + count;
nw.lines = wr.lines;
int grep = count;
while(grep > 0)
{
nw.lines.addElement(ps.b + j);
grep--;
}
this.ps.hm.put(keyWords.elementAt(i), nw);
}
else
{
Word nw = new Word(ps.fileName);
nw.nrap = count;
int grep = count;
while(grep > 0)
{
nw.lines.addElement(ps.b + j);
grep--;
}
this.ps.hm.put(keyWords.elementAt(i), nw);
}
}
}
else
{
String regex = keyWords.elementAt(i).substring(1, keyWords.elementAt(i).length() - 1);
StringBuffer sb = new StringBuffer(regex);
regex = sb.toString();
Pattern pt = Pattern.compile(regex);
Matcher m = pt.matcher(st[j]);
int count = 0;
while(m.find())
{
count++;
}
if(count != 0)
{
Word wr = this.ps.hm.get(keyWords.elementAt(i));
if(wr != null)
{
Word nw = new Word(this.ps.fileName);
nw.nrap = wr.nrap + count;
nw.lines = wr.lines;
int grep = count;
while(grep > 0)
{
nw.lines.addElement(ps.b + j);
grep--;
}
this.ps.hm.put(keyWords.elementAt(i), nw);
}
else
{
Word nw = new Word(this.ps.fileName);
nw.nrap = count;
int grep = count;
while(grep > 0)
{
nw.lines.addElement(ps.b + j);
grep--;
}
this.ps.hm.put(keyWords.elementAt(i), nw);
}
}
}
}
}
this.ps.info = null;
return this.ps;
}
}
所以在地图我从该片段的每一行,并搜索每个表达式数的外观,我也保存线的数量。在我处理完所有片段后,在同一个PartialSolution中,我将这些信息保存在散列图中并返回新的PartialSolution。在下一步中,我将PartialSolutions与相同的fileName结合起来,并将它们引入Callable类Reduce中,它与map相同,不同之处在于它可以进行其他操作,但也返回PartialSolution。
这是跑地图的任务代码:
List<Future<PartialSolution>> list = new ArrayList<Future<PartialSolution>>();
Collection<Callable<PartialSolution>> tasks = new ArrayList<Callable<PartialSolution>>();
for(PartialSolution ps : wp)
{
tasks.add(new Map(ps, keyWords));
}
list = executor.invokeAll(tasks);
在任务我创建类型地图的任务,并在列表中我得到他们。我不知道如何读取JVM线程转储。我希望能够提供给我的信息。如果有帮助,我在NetBeans 7.0.1中工作。
谢谢 亚历
多少任务,你呢?他们做什么?有很多I/O? – Thilo
我的任务是那些可调用的类,它们使用PartialSolution,它有一些文本并计算一个单词出现文本和行的次数。 PartialSolution实际上是文本的一部分,我希望为每个部分获取这些信息,然后将它们与另一个名为Reduce的Callable类联合起来。我想同时处理这些零件。取决于我拥有的处理器数量。 I/O将在最后,当我将所有任务和10个部分联合起来说,并将有一个关于该文件的所有信息。 Google使用的是MapReduce。 –
我想知道的是,如果方法invokeAll,如果我创建了10个线程的ExcutorService,将同时解决10个任务或一次解决一个任务?在Map中我有一个构造函数,并实现了函数call(),该函数返回另一个PartialSolution,但是这次是正确的信息。还有一个问题,如果我说list.get(i).get()这将返回PartialSolution解决之后赖特? 我真的不明白为什么不改善时间,如果我使用2线程而不是1.为什么它不缩放赖特? –