У меня есть класс FeatOrientation, и в этом классе в его конструкторе я выполняю две операции каждый в отдельном потоке, и я использую CountDownLatch, так что, когда gaussThread заканчивает запуск laplaceThread.ExecutorService не блокируется до тех пор, пока нить finishe
и в основном классе, который имеет основной метод, я использую ExecutorService и в «.runAsync (новый FeatOrientRun (bgrMat), featOrientExe);
В методе выполнения я называю функцию calcFeatOrient и в этой функции я создаю объект из класса FeatOrientation. и линия
"CompletableFuture.allOf(future0).join();"
я использовал его, чтобы блокировать основной поток до двух потоков в классе FeatOrientation finih, а затем я сделать некоторые вычисления или отображать некоторые данные, как и в
"Log.D(TAG, "MainClass", "SmoothedImgList:" + fo.getSmoothedImgList().size());".
проблема, во время выполнения я получаю вывод, показанный ниже из консоли despit. 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();
и я экземпляр объекта из класса FeatOrientation в основном методе, а затем сделал основной поток спать в течение 7 секунд и после 7 секунд, я назвал следующие строки:
и я получил выход.
Пожалуйста, дайте знать, что я делаю неправильно с ExecutorService, и почему подход, который я следую ниже, не работает desoite, я жду, пока класс 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();
}
}
спасибо за ваш ответ. фактически я не ожидаю результатов от CompletableFuture.runAsync (новый FeatOrientRun (bgrMat), featOrientExe); , я просто хочу подождать, пока он закончится, так что я могу делать некоторые операции – user2121
@ user2121, если вы понимаете, что даже когда задача завершается, это не значит, что вы можете использовать результаты этой задачи в другом потоке, если только вы считаете безопасность потока. –
@ user2121, точка зрения Питера заключается в том, что в то время вы выполняете только одну задачу, поэтому почему бы не сделать все это в одном потоке, вместо того, чтобы размножать несколько потоков для выполнения задач один за другим. – Kishore