У меня четыре потока выполняется асинхронно, используя CompletableFuture, как показано ниже в коде. и все они должны получить доступ к «growSeedXYList». когда я запускаю код, я не получаю никаких ошибок, но некоторое время я получаю «java.util.concurrent.completionexception» , и я думаю, это потому, что «growSeedXYList» не синхронизирован.Как избежать параллельного доступа к ресурсу?
, пожалуйста, дайте мне знать, как синхронизировать «growSeedXYList»?
обновление:
this.grownSeedXYList is a list that will be populated with some Point objects based on the runnable class used (GrowSeedSERun, GrowSeedNWRun, GrowSeedNERun, GrowSeedSWRun)
четыре нити запускаются с использованием Compltable будущего
this.grownSeedXYList = new ArrayList<Point>();
this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedSERun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor);
this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedNWRun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor);
this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedNERun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor);
this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedSWRun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor);
CompletableFuture.allOf(this.growSeedFutureList).join();
GrowSeedSERun класс:
private class GrowSeedSERun implements Runnable {
private Mat saliencyMat = null;
private double seedVal;
private Point seedXY = null;
public GrowSeedSERun(Mat saliencyMat, Point seedXY, double seedVal) {
// TODO Auto-generated constructor stub
this.saliencyMat = saliencyMat;
this.seedXY = seedXY;
this.seedVal = seedVal;
}
public void run() {
// TODO Auto-generated method stub
growSeedsSE(this.saliencyMat, this.seedXY, this.seedVal);
}
}
growSeedsSE:
private void growSeedsSE(Mat saliencyMat, Point seedXY, Double seedVal) {
// TODO Auto-generated method stub
int origX = (int) seedXY.x;
int origY = (int) seedXY.y;
if (this.withinRange(saliencyMat.get(origY, ++origX)[0])) {
if ((this.grownSeedXYList != null) && (!this.grownSeedXYList.contains(new Point(origX, origY)))) {
//Log.D(TAG, "growSeedsSE", "newX: origX: "+origX);
//Log.D(TAG, "growSeedsSE", "newX: origY: "+origY);
//Log.D(TAG, "growSeedsSE", "newX: value: "+saliencyMat.get(origY, origX)[0]);
this.grownSeedXYList.add(new Point(origX, origY));
} else {
Log.D(TAG, "growSeedsSE", "point: "+ new Point(origX, origY)+" contained in the list");
}
this.growSeedsSE(this.saliencyMat, new Point(origX, origY), this.saliencyMat.get(origY, origX)[0]);
} else if (this.withinRange(saliencyMat.get(++origY, (int) this.seedXY.x)[0])) {
origX = (int) this.seedXY.x;
if ((this.grownSeedXYList != null) && (!this.grownSeedXYList.contains(new Point(origX, origY)))) {
//Log.D(TAG, "growSeedsSE", "newY: origX: "+origX);
//Log.D(TAG, "growSeedsSE", "newY: origY: "+origY);
//Log.D(TAG, "growSeedsSE", "newY: value: "+saliencyMat.get(origY, origX)[0]);
this.grownSeedXYList.add(new Point(origX, origY));
} else {
Log.D(TAG, "growSeedsSE", "point: "+ new Point(origX, origY)+" contained in the list");
}
this.growSeedsSE(this.saliencyMat, new Point(origX, origY), this.saliencyMat.get(origY, origX)[0]);
}
}
Вы не показали нам, что 'grownSeedXYList 'есть или где он инициализирован или объявлен. Кроме того, если вы получаете «CompletionException», разместите его stacktrace. –
Вы повторно присваиваете 'growSeedFutureList' четыре раза подряд. В чем цель этого? Вы пытаетесь добавить новые 'CompletableFutures' в' List'? –
Итак, это 'ArrayList'. 'ArrayList' не являются потокобезопасными, поэтому, если вы используете один и тот же экземпляр для потоков, у вас проблемы. –