私はマルチスレッドが初めてで、効率を上げるために複数のスレッドを使用するプログラムを作成する必要があります。私の最初の試みでは、私が書いたものは正反対の結果をもたらしました。ここに私が書いたものがあります:
class ThreadImpl implements Callable<ArrayList<Integer>> {
//Bloom filter instance for one of the table
BloomFilter<Integer> bloomFilterInstance = null;
// Data member for complete data access.
ArrayList< ArrayList<UserBean> > data = null;
// Store the result of the testing
ArrayList<Integer> result = null;
int tableNo;
public ThreadImpl(BloomFilter<Integer> bloomFilterInstance,
ArrayList< ArrayList<UserBean> > data, int tableNo) {
this.bloomFilterInstance = bloomFilterInstance;
this.data = data;
result = new ArrayList<Integer>(this.data.size());
this.tableNo = tableNo;
}
public ArrayList<Integer> call() {
int[] tempResult = new int[this.data.size()];
for(int i=0; i<data.size() ;++i) {
tempResult[i] = 0;
}
ArrayList<UserBean> chkDataSet = null;
for(int i=0; i<this.data.size(); ++i) {
if(i==tableNo) {
//do nothing;
} else {
chkDataSet = new ArrayList<UserBean> (data.get(i));
for(UserBean toChk: chkDataSet) {
if(bloomFilterInstance.contains(toChk.getUserId())) {
++tempResult[i];
}
}
}
this.result.add(new Integer(tempResult[i]));
}
return result;
}
}
上記のクラスには 2 つのデータ メンバーがdata
ありbloomFilterInstance
、それら (参照) はメイン プログラムから渡されます。したがって、実際には data と BloomFilterInstance のインスタンスは 1 つしかなく、すべてのスレッドが同時にアクセスしています。
スレッドを起動するクラスは次のとおりです (無関係な詳細はほとんど省略されているため、すべての変数などは宣言されていると見なすことができます):
class MultithreadedVrsion {
public static void main(String[] args) {
if(args.length > 1) {
ExecutorService es = Executors.newFixedThreadPool(noOfTables);
List<Callable<ArrayList<Integer>>> threadedBloom = new ArrayList<Callable<ArrayList<Integer>>>(noOfTables);
for (int i=0; i<noOfTables; ++i) {
threadedBloom.add(new ThreadImpl(eval.bloomFilter.get(i),
eval.data, i));
}
try {
List<Future<ArrayList<Integer>>> answers = es.invokeAll(threadedBloom);
long endTime = System.currentTimeMillis();
System.out.println("using more than one thread for bloom filters: " + (endTime - startTime) + " milliseconds");
System.out.println("**Printing the results**");
for(Future<ArrayList<Integer>> element: answers) {
ArrayList<Integer> arrInt = element.get();
for(Integer i: arrInt) {
System.out.print(i.intValue());
System.out.print("\t");
}
System.out.println("");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
jprofilerでプロファイリングを行い、
![こちら]:(http://tinypic.com/r/wh1v8p/6)
は CPU スレッドのスナップショットです。赤色はブロックされていることを示し、緑色は実行可能であり、黄色は待機中です。私の問題は、スレッドが一度に 1 つずつ実行されていることです。理由がわかりません。
注: これはスレッド セーフではないことはわかっていますが、今のところ読み取り操作のみを実行し、達成可能な生のパフォーマンスの向上を分析したいだけであることはわかっています。後で、より良いバージョンを実装します。