質問

私はJavaでプログラムを使用して書き込もうとしています ExecutorService およびその機能 invokeAll. 。私の質問は次のとおりです invokeAll 機能タスクを同時に解決しますか?つまり、2つのプロセッサがある場合、同時に2人の労働者がいるでしょうか? 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;
    }
}

したがって、マップでは、フラグメントからすべての行を取り、すべての式を検索して、外観の数を検索し、ラインの数も保存します。すべてのフラグメントを処理した後、同じ部分断線でハッシュマップに情報を保存して、新しい部分溶解を返します。次のステップでは、部分的なソリューションを同じファイル名と組み合わせて、MAPと同じ呼び出し可能なクラス削減でそれらを紹介します。違いは、他の操作を作るが、部分的な解決策も戻すことです。

これは、マップタスクを実行するコードです。

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個のスレッドでExcutorserviceを作成した場合、Method Invokeallが10個のタスクを同時に解決するか、1つずつ1つずつ解決するかどうかです。

10個のスレッドを使用して10個のタスクをexecutorserviceに送信すると、それらはすべて同時に実行されます。彼らがそれぞれから完全に平行で独立して進めることができるかどうかは、彼らが何をしているかによって異なります。しかし、彼らはそれぞれ独自のスレッドを持っています。

そして、別の質問、私がlist.get(i).get()と言ったら、これは解決された後に部分的なソリューションを返しますか?

はい、計算が完了するまで(まだ実行されていない場合)ブロックし、結果を返します。

1の代わりに2つのスレッドを使用する場合、なぜ時間が改善されないのか本当にわかりません。

もっとコードを見る必要があります。それらはいくつかの共有データで同期していますか?これらのタスクにはどのくらい時間がかかりますか?それらが非常に短い場合、あなたは違いに気付かないかもしれません。時間がかかる場合は、JVMスレッドダンプを見て、すべてが実行されていることを確認してください。

他のヒント

2つのスレッドでスレッドプールを作成すると、2つのタスクが同時に実行されます。

2つのスレッドが1つのスレッドと同じ時間をかける可能性があると思うことが2つあります。

マップタスクの1つだけが時間をかけている場合、追加のスレッドはその1つのタスクがより速く実行されません。最も遅い仕事よりも速く終わることはできません。

もう1つの可能性は、マップタスクが共有ベクトルから頻繁に読み取られることです。これにより、2つのスレッドを持つことでゲインをキャンセルするのに十分な競合が発生する可能性があります。

JVisualVmでこれを持ち出して、各スレッドが何をしているのかを確認する必要があります。

Java 8は、もう1つのAPIを導入しました 執行者-NEWWORKSTELINGPOOL 仕事を盗むプールを作成します。作成する必要はありません 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.

また executorservice また Forkjoinpool また ThreadPoolexecutor 共有データと共有ロック(同期)とスレッド間通信がない場合は、パフォーマンスが適しています。タスクキューですべてのタスクが互いに独立している場合、パフォーマンスは改善されます。

ThreadPoolExecutor タスクのワークフローをカスタマイズおよび制御するためのコンストラクター:

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

関連するSEの質問を見てください:

Java executorを適切に使用する方法は?

Java's Fork/Joinvs executorservice-どちらを使用するのか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top