次のマルチスレッドプログラムを作成しました。スレッドの1つがfalseを返す場合、すべてのスレッドをキャンセルしたい。ただし、個々のタスクをキャンセルしてスレッドをキャンセルしていますが。動いていない。スレッドをキャンセルするには、どのような変更を加える必要がありますか?
次のマルチスレッドプログラムを作成しました。スレッドの1つがfalseを返す場合、すべてのスレッドをキャンセルしたい。ただし、個々のタスクをキャンセルしてスレッドをキャンセルしていますが。動いていない。スレッドをキャンセルするには、どのような変更を加える必要がありますか?
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
public class BeamWorkerThread implements Callable<Boolean> {
private List<BeamData> beamData;
private String threadId;
public BeamScallopingWorkerThread(
List<BeamData> beamData, String threadId) {
super();
this.beamData = beamData;
this.threadId = threadId;
}
@Override
public Boolean call() throws Exception {
Boolean result = true;
DataValidator validator = new DataValidator();
Iterator<BeamScallopingData> it = beamData.iterator();
BeamData data = null;
while(it.hasNext()){
data = it.next();
if(!validator.validateDensity(data.getBin_ll_lat(), data.getBin_ll_lon(), data.getBin_ur_lat(), data.getBin_ur_lon())){
result = false;
break;
}
}
return result;
}
}
ExecutorService threadPool = Executors.newFixedThreadPool(100);
List<Future<Boolean>> results = new ArrayList<Future<Boolean>>();
long count = 0;
final long RowLimt = 10000;
long threadCount = 1;
while ((beamData = csvReader.read(
BeamData.class, headers1, processors)) != null) {
if (count == 0) {
beamDataList = new ArrayList<BeamData>();
}
beamDataList.add(beamData);
count++;
if (count == RowLimt) {
results.add(threadPool
.submit(new BeamWorkerThread(
beamDataList, "thread:"
+ (threadCount++))));
count = 0;
}
}
results.add(threadPool.submit(new BeamWorkerThread(
beamDataList, "thread:" + (threadCount++))));
System.out.println("Number of threads" + threadCount);
for (Future<Boolean> fs : results)
try {
if(fs.get() == false){
System.out.println("Thread is false");
for(Future<Boolean> fs1 : results){
fs1.cancel(true);
}
}
} catch(CancellationException e){
} catch (InterruptedException e) {
} catch (ExecutionException e) {
} finally {
threadPool.shutdownNow();
}
}
私のコメント
ご意見をお寄せいただきありがとうございます。反応に圧倒されています。私は、よく実装されたスレッドがアプリを最高に引き上げ、悪い実装がアプリをひざまずかせることを知っています. 私は空想的なアイデアを持っていることに同意しますが、他に選択肢はありません。私は1000万以上の記録を持っているので、メモリの制約と時間の制約があります。両方に取り組む必要があります。したがって、データ全体を飲み込むのではなく、チャンクに分割しています。また、1 つのデータが無効な場合、残りの 100 万個のデータの処理に時間を無駄にしたくありません。@Mark Petersの提案はオプションだと思います。それに応じて変更を加えたということは、タスクを中断するフラグを追加したことを意味し、将来のリストがどのように機能するかについてかなり混乱しています。私が理解しているのは、すべてのスレッドがその値を返すと、将来のリストの各フィールドのループが開始されるということです。その場合、メイン リストからすべてのタスクを途中でキャンセルする方法はありません。オブジェクトの参照を各スレッドに渡す必要があります。1 つのスレッドがスレッド参照を使用して無効なデータを見つけた場合、各スレッドのキャンセル メソッドを呼び出して、割り込みフラグを設定します。
while(it.hasNext() && !cancelled) {
if(!validate){
// loop through each thread reference and call Cancel method
}
}