這實際上是一個半問題,半討論帖。 我覺得需要在Java中的特徵是,方法(可以說「calcTotalX」)可通過在一類(即ParallelExecuter),這將執行的另一方法的beforeStart/AfterEnd註解來限定(可以說doJob)在同一類。因此,我們可以確定,任何擴展ParallelExecuter的類(可以說SortingParallelExecuter)並重寫其「doJob」方法不必知道X,可能會遺忘處理X,處理有關X的操作事件等。Java繼承和OOP和AOP
My問題是,Java中有沒有什麼可以像這樣做,除了AOP。 我不選擇AOP,因爲它會使代碼分佈太多而且難以閱讀。 另外這裏關注的是類/方法/屬性的具體情況。因此其他類/方法/屬性不需要複製行爲。
順便說一句,如果你發現這個合理的,請投票支持線程。日Thnx
好,爲是具體的我加入,我用分割& paralelization樣本類。
public abstract class PartitionedParallelExecutor<T> {
private ExecutorService executorService;
private final List<PartitionErrorDesc<T>> errorMap = new ArrayList<PartitionErrorDesc<T>>();
private final AtomicInteger totalExecutedJobCount = new AtomicInteger();
private boolean shutdownForced = false;
private final int workerCount;
private final int partitionCount;
protected final List<T> sourceList;
//Must be implemented via Extender class
protected abstract PartitionErrorDesc<T> doWork(List<T> subList);
public PartitionedParallelExecutor(int workerCount, int partitionCount, List<T> sourceList) {
super();
this.workerCount = workerCount;
this.partitionCount = partitionCount;
this.sourceList = sourceList;
}
public Object onPerPartitionFail(List<T> subList, PartitionErrorDesc<T> ped){return null;};
public Object onPerPartitionSuccess(List<T> subList){return null;};
public Object onAnyFailDoOnce() {return null;}
public Object onTotalSuccess() {return null;}
public final void fireAndWait() {
if(workerCount <= 0 || partitionCount <= 0 ||
sourceList == null || sourceList.size() == 0){
throw new IllegalArgumentException();
}
ExecutorService executorService = Executors.newFixedThreadPool(workerCount);
this.executorService = executorService;
List<List<T>> partitions = partitionList(sourceList, partitionCount);
for (final List<T> subList : partitions) {
executorService.execute(new Runnable() {
@Override
public void run() {
PartitionErrorDesc<T> errorDesc = null;
try {
errorDesc = doWork(subList);
} catch (Throwable e) {
errorDesc = new PartitionErrorDesc<T>(subList);
errorDesc.setSuccess(false);
errorDesc.setE(e);
errorDesc.setFailedAtItem(0);
}
errorMap.add(errorDesc);
if(errorDesc.isSuccess == false) { //failure
onPerPartitionFail(subList, errorDesc);
setShutdownForced(true);
totalExecutedJobCount.addAndGet(errorDesc.getFailedAtItem());
Thread.currentThread().interrupt();
return;
} else { //success
totalExecutedJobCount.addAndGet(subList.size());
onPerPartitionSuccess(subList);
}
}
});
}
executorService.shutdown();
try {
executorService.awaitTermination(60, TimeUnit.MINUTES);
} catch (InterruptedException e) {
setShutdownForced(true);
Thread.currentThread().interrupt();
}
if (!isShutdownForced()) {
onTotalSuccess();
} else {
onAnyFailDoOnce();
}
}
private List<List<T>> partitionList(List<T> sourceList , int partitionCount) {
List<List<T>> partitions = new ArrayList<List<T>>();
int totalSize = sourceList.size();
int pageCount = partitionCount;
int pageSize = totalSize/pageCount;
int remainder = totalSize % (pageSize * pageCount);
int fromIndex = 0;
int toIndex = 0;
for(int i = 0; i < pageCount; i++) {
fromIndex = toIndex;
if(toIndex >= totalSize){
break;
}
if (remainder > i) {
toIndex = toIndex + pageSize + 1;
} else {
toIndex = toIndex + pageSize;
}
List<T> subList = sourceList.subList(fromIndex,toIndex);
partitions.add(subList);
}
return partitions;
}
public final void shutdownNow() {
setShutdownForced(true);
List<Runnable> runnables = executorService.shutdownNow();
try {
if(!executorService.awaitTermination(60,TimeUnit.SECONDS)) {
LOG.error("pool didnt terminate after 60 seconds in shutdownNow");
}
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt();
}
}
public final boolean isShutdownForced() {
return shutdownForced;
}
private synchronized void setShutdownForced(boolean shutdownForced) {
this.shutdownForced = shutdownForced;
}
}
在這個例子中,誰願意使用上面做他的工作在一個多線程的方式類的程序員,他必須執行「doJob()」,但援引「fireAndWait() 」。實現doJob &調用doJob將會是一個更加整潔的方式。剩下的東西像計算「totalExecutedJobCount」,onPerPartitionFail()必須以AOP方式交叉切割爲「doJob」方法。是的,我們可以在另一個類中實現此功能,但任何擴展PartitionedParallelExecutor的類都可以擴展此AOP行爲,正如我所知。在這一點上,我問,爲什麼這些東西(計算「totalExecutedJobCount」,onPerPartitionFail())必須在另一個類。它們與這個類,它的屬性和方法有關。以面向對象的方式來看,它們必須在同一個類中有一些方法,並在「doJob」結束時調用。就是那個問題。現在希望事情很清楚。 Thnx你的時間。
您對AOP的偏見沒有任何意義。我建議你先告訴你自己並在你說它「難以閱讀」之前先試用它,因爲這不正確。分散式?不,相反:方面代碼很好地模塊化。它很容易閱讀,因爲它是乾淨的,沒有橫切關注的核心代碼。 – kriegaex
thnx您的評論,但我已經使用Spring AOP。 –
Spring AOP是「AOP light」,只是在Spring Beans上攔截方法。雖然語法等同於AspectJ,但後者有更多的可能性,並且效率更高,因爲它不需要任何動態代理。它適用於非Spring Bean(即普通的POJO),可以攔截成員變量的讀/寫操作,構造函數調用,靜態類初始化,catch塊等等。但最重要的是沒有容易出錯的基於字符串的註釋風格的本地語法。 – kriegaex