クラス FeatOrientation があり、そのクラスのコンストラクターで、2 つの操作をそれぞれ別のスレッドで実行し、CountDownLatch を使用して、gaussThread が終了すると laplaceThread が開始されるようにします。
メインメソッドを持つメインクラスでは ExecutorService を使用しており、「.runAsync(new FeatOrientRun(bgrMat), featOrientExe);」
run メソッドで「calcFeatOrient」関数を呼び出し、その関数で FeatOrientation クラスからオブジェクトをインスタンス化します。そしてライン
"CompletableFuture.allOf(future0).join();"
私はそれを使用して、FeatOrientation クラスの 2 つのスレッドが終了するまでメイン スレッドをブロックし、次に計算を実行するか、次のようにデータを表示します。
"Log.D(TAG, "MainClass", "SmoothedImgList:" + fo.getSmoothedImgList().size());".
問題は、実行時に、getSmoothedImgList が空でないにもかかわらず、コンソールから以下に示す出力を受け取ることです。次の3行をコメントアウトすることで、空ではないことがわかりました。
featOrientExe = Executors.newFixedThreadPool(1);
future0 = CompletableFuture.runAsync(new FeatOrientRun(bgrMat), featOrientExe);
CompletableFuture.allOf(future0).join();//blocks the main thread till future0, and future1 finishes
featOrientExe.shutdown();
メインメソッドでFeatOrientationクラスからオブジェクトをインスタンス化し、メインスレッドを7秒間スリープさせ、7秒後に次の行を呼び出しました
Log.D(TAG, "MainClass", "SmoothedImgList:" + fo.getSmoothedImgList().size());
Log.D(TAG, "MainClass", "SubSampledImgList:" + fo.getSubSampledImgList().size());
for (int i = 0; i < fo.getSmoothedImgList().size(); i++) {
ImageUtils.showMat(fo.getSmoothedImgList().get(i), "SmoothedImgList_" + i);
}
for (int i = 0; i < fo.getSubSampledImgList().size(); i++) {
//Mat laplaceImg = SysUtils.applyLaplac(fo.getSubSampledImgList().get(i));
//ImageUtils.showMat(laplaceImg, "getSubSampledImgList" + i);
}
そしてアウトアウトを受け取りました。
私が ExecutorService で何を間違っているか、および以下に投稿されたコードで私が従っているアプローチが機能しない理由を教えてください。FeatOrientation クラスが機能し終わるまで待ちます。
コンソール出力:
1: Error: FeatOrientation -> getSmoothedImgList: smoothedImgList is empty
Exception in thread "main" java.lang.NullPointerException
at com.example.featorientation_00.MainClass.main(MainClass.java:39)
メインクラス:
public static void main(String[] args) {
MatFactory matFactory = new MatFactory();
FilePathUtils.addInputPath(path_Obj);
Mat bgrMat = matFactory.newMat(FilePathUtils.getInputFileFullPathList().get(0));
featOrientExe = Executors.newFixedThreadPool(1);
future0 = CompletableFuture.runAsync(new FeatOrientRun(bgrMat), featOrientExe);
CompletableFuture.allOf(future0).join();//blocks the main thread till future0, and future1 finishes
featOrientExe.shutdown();
Log.D(TAG, "MainClass", "SmoothedImgList:" + fo.getSmoothedImgList().size());
Log.D(TAG, "MainClass", "SubSampledImgList:" + fo.getSubSampledImgList().size());
for (int i = 0; i < fo.getSmoothedImgList().size(); i++) {
ImageUtils.showMat(fo.getSmoothedImgList().get(i), "SmoothedImgList_" + i);
}
for (int i = 0; i < fo.getSubSampledImgList().size(); i++) {
//Mat laplaceImg = SysUtils.applyLaplac(fo.getSubSampledImgList().get(i));
//ImageUtils.showMat(laplaceImg, "getSubSampledImgList" + i);
}
}
static class FeatOrientRun implements Runnable {
private Mat bgrMat;
public FeatOrientRun(Mat bgrMat) {
// TODO Auto-generated constructor stub
this.bgrMat = bgrMat;
}
public void run() {
// TODO Auto-generated method stub
calcFeatOrient(this.bgrMat);
}
}
public static void calcFeatOrient(Mat bgrMat) {
// TODO Auto-generated method stub
fo = new FeatOrientation(bgrMat);
}
FeatOrientation クラス:
public FeatOrientation(Mat bgrMat) {
// TODO Auto-generated constructor stub
this.origBGRImgList = new ArrayList<Mat>();
this.origGSImgList = new ArrayList<Mat>();
this.smoothedImgList = new ArrayList<Mat>();
this.downSampledImgList = new ArrayList<Mat>();
this.laplaceImgList = new ArrayList<Mat>();
this.latch = new CountDownLatch(1);
if (bgrMat != null) {
if (!bgrMat.empty()) {
if (bgrMat.channels() == 3) {
if ( (bgrMat.size().width >= SysConsts.MIN_IMG_WIDTH) && (bgrMat.size().height >= SysConsts.MIN_IMG_HEIGHT) ) {
this.bgrMat = bgrMat;
this.gaussThread = new Thread(new GaussRun(this.bgrMat, this.latch), "GAUSSIAN_THREAD");
this.laplaceThread = new Thread(new LaplaceRun(this.latch), "GAUSSIAN_THREAD");
this.gaussThread.start();
this.laplaceThread.start();
} else {
Log.E(TAG, "FeatOrientation", "the Mat you passed to the constructor has size: " + this.bgrMat.size() +
" the minimum width must = " + SysConsts.MIN_IMG_WIDTH +
" and the maximum height must = " + SysConsts.MIN_IMG_HEIGHT);
}
} else {
Log.E(TAG, "FeatOrientation", "BGR mat passed to the constructor does not has 3 channels.");
}
} else {
Log.E(TAG, "FeatOrientation", "BGR mat passed to the constructor is empty");
}
} else {
Log.E(TAG, "FeatOrientation", "the BGR mat you passed to the constructor is null");
}
}
class GaussRun implements Runnable {
private Mat bgrMat;
private CountDownLatch latch;
public GaussRun(Mat bgrMat, CountDownLatch latch) {
// TODO Auto-generated constructor stub
this.bgrMat = bgrMat;
this.latch = latch;
}
public void run() {
// TODO Auto-generated method stub
applyGaussianPyr(this.bgrMat);
this.latch.countDown();
}
}
class LaplaceRun implements Runnable {
private CountDownLatch latch;
public LaplaceRun(CountDownLatch latch) {
// TODO Auto-generated constructor stub
this.latch = latch;
}
public void run() {
// TODO Auto-generated method stub
try {
this.latch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
applyLaplacianPyr();
}
}