我有一个 FeatOrientation 类,在它的构造函数中的那个类中,我在一个单独的线程中执行两个操作,每个操作都在一个单独的线程中执行,并且我正在使用 CountDownLatch 以便当 gaussThread 完成时 laplaceThread 启动。
在具有主要方法的主类中,我正在使用 ExecutorService 和“.runAsync(new FeatOrientRun(bgrMat), featOrientExe);”
在运行方法中,我调用“calcFeatOrient”函数,并在该函数中从 FeatOrientation 类实例化一个对象。和线
"CompletableFuture.allOf(future0).join();"
我用它来阻塞主线程,直到 FeatOrientation 类中的两个线程完成,然后我进行一些计算或显示一些数据,如
"Log.D(TAG, "MainClass", "SmoothedImgList:" + fo.getSmoothedImgList().size());".
问题是,在运行时我从控制台收到下面显示的输出,尽管 getSmoothedImgList 不为空。通过注释掉以下三行,我知道它不是空的:
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();
我在 main 方法中从 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);
}
我收到了outout。
请让我知道我在 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();
}
}