我正在尝试使用Java编写程序 ExecutorService 及其功能 invokeAll. 。我的问题是:是否 invokeAll 功能同时解决任务?我的意思是,如果我有两个处理器,将同时有两名工人?因为AI无法正确扩展。如果我给予问题,则需要相同的时间来完成问题 newFixedThreadPool(2) 或1。

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 是实施的课程 Callablewp 是部分解决方案的向量,该类别在不同时间内拥有一些信息。

为什么不扩展?可能是什么问题呢?

这是部分解决的代码:

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;
    }
}

因此,在地图中,我从片段中获取每一行,并搜索每个表达式的外观数量,我还保存了行的数量。处理所有片段后,在同一部分解决方案中,我将信息保存在哈希地图中,然后返回新的部分解决方案。在下一步中,我将部分溶液与相同的文件名相结合,并将它们介绍为可召唤的类Repar,与地图相同,区别在于它做出其他操作,但返回也是部分解决方案。

这是运行地图任务的代码:

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工作。

谢谢你,亚历克斯

有帮助吗?

解决方案

我想知道的是,如果我使用10个线程创建了cocutorService的方法,将同时解决10个任务,或者一次求解一个任务?

如果您将十个任务提交给具有十个线程的执行人员服务,则将同时运行它们。他们是否可以完全平行和独立地进行彼此之间的行动取决于他们在做什么。但是他们每个人都有自己的线程。

还有另一个问题,如果我说列表。

是的,它将阻止,直到完成计算(如果尚未完成)并返回其结果。

我真的不明白,如果我使用2个线程而不是1个线程,为什么没有时间改善。

我们需要查看更多代码。他们是否同步一些共享数据?这些任务需要多长时间?如果它们很短,您可能不会注意到任何区别。如果他们花费更长的时间,请查看JVM线程转储以验证所有这些都在运行。

其他提示

如果使用两个线程创建线程池,则将同时运行两个任务。

我看到的两件事可能导致两个线程的时间与一个线程相同的时间。

如果您的地图任务中只有一个时间花费您的大部分时间,那么额外的线程就不会使一个任务运行速度更快。它不能比最慢的工作更快。

另一种可能性是您的地图任务经常从共享向量读取。这可能导致足够的争论从拥有两个线程中取消增益。

您应该在JVisualVM中提出此内容,以查看每个线程在做什么。

Java 8在 执行者 - 新Workstealingpool 创建工作偷池。您不必创建 RecursiveTaskRecursiveAction 但仍然可以使用 ForkJoinPool.

public static ExecutorService newWorkStealingPool()

使用所有可用的处理器作为其目标并行性级别创建一个偷窃线程池。

默认情况下,它将将CPU核心数作为并行性的参数。如果您有核心CPU,则可以有8个线程来处理工作任务队列。

Work stealing of idle worker threads from busy worker threads improves overall performance. Since task queue is unbounded in nature, this ForkJoinPool is recommended for the tasks executing in short time intervals.

任何一个 执行人员服务 或者 forkjoinpool 或者 ThreadPoolExecutor 如果您没有共享数据和共享锁定(同步)和线程间通信,则性能将是好的。如果所有任务在任务队列中彼此独立,则将提高性能。

ThreadPoolExecutor 定制和控制任务工作流程的构造函数:

 ThreadPoolExecutor(int corePoolSize, 
                       int maximumPoolSize, 
                       long keepAliveTime, 
                       TimeUnit unit, 
                       BlockingQueue<Runnable> workQueue, 
                       ThreadFactory threadFactory,
                       RejectedExecutionHandler handler)

看看相关的SE问题:

如何正确使用Java遗嘱执行人?

Java的叉/加入vs executorService-何时使用?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top