我正在使用java.util.concurrent.ExecutorService
對所有可用處理資源執行併發計算。在下面的代碼中,MyProcessor
類的實例在其performParallelProcessing
方法中創建了多個ProcessingExecutor
類實例,並將它們提交給ExecutorService
實例,以期獲得相應的回調。爲什麼Java併發處理不適用於新實例化的對象,而它適用於同一類的反序列化對象?
處理髮生在ProcessingExecutor
類的performProcessing
方法中。我用於處理的數據是類ComputationData
的對象實例。它們可以從文件系統中檢索(如果序列化數據存在),或者可以初始化爲新實例。
這裏的問題是:
在這種情況下,如果ComputationData
對象實例從文件系統反序列化,並行處理執行,因爲我希望它做的事。它在所有處理核心上並行運行,佔用了100%的處理資源。
在ComputationData
對象實例被新初始化的情況下,併發處理不按照我的預期執行。它的運行就像是單線程執行,佔用了大約15%的處理資源。
正如我所猜,我的新初始化的ComputationData
對象實例有問題。但是我不知道他們有什麼問題,以及爲什麼併發不適用於他們,而他們的序列化 - >反序列化版本。任何提示或想法將不勝感激。
public class MyProcessor {
private boolean processingFinished = false;
public void performParallelProcessing(){
int count = 0;
boolean continueProcessing = true;
int nrOfProcessors = Runtime.getRuntime().availableProcessors();
ExecutorService es = Executors.newFixedThreadPool(nrOfProcessors);
while (continueProcessing){
ProcessingExecutor task = new ProcessingExecutor(count);
task.setCaller(this);
es.submit(task);
count++;
if (!processingFinished){
try{
Thread.sleep(50);
}
catch(SecurityException | InterruptedException e){
//Exception handling
}
}
else{
continueProcessing = false;
}
}
}
public void callBack(ProcessingResult result) {
if(result.allDataProcessed()){
this.processingFinished = true;
}
}
}
public class ProcessingExecutor implements Callable {
private MyProcessor processor;
private int count;
public ProcessingExecutor(int count){
this.count = count;
}
public Object call() {
ProcessingResult result = null;
try {
result = performProcessing();
}
catch (SecurityException e) {
//Exception handling
}
processor.callBack(result);
return null;
}
public void setCaller(MyProcessor processor) {
this.processor = processor;
}
public MyProcessor getCaller() {
return this.processor;
}
private ProcessingResult performProcessing(){
ComputationData data = null;
if(serializedDataExist()){
data = getSerializedData(count);
}
else{
data = initializeNewData(count);
}
ProcessingResult result = new ProcessingResult(data, count);
return result;
}
private ComputationData getSerializedData(int count){
ComputationData data = null;
// code to retrieve a ComputationData object from the file system
// based on 'count' value.
return data;
}
private ComputationData initializeNewData(int count){
ComputationData data = null;
// code to initialize a new instance of ComputationData class
// based on 'count' value.
return data;
}
private boolean serializedDataExist(){
boolean dataFound = false;
// code to verify whether serialized ComputationData objects are
// present on the file system.
return dataFound;
}
}
如果您認爲問題出在ComputationData類上,那麼將它包含在問題中是一個好主意。 – biziclop
你有沒有使用探查器來追蹤發生了什麼?我的猜測是反序列化是一直需要的,所以當你不這樣做時,它會更快地完成,並且需要更少的cpu –
序列化是CPU密集型過程,而分配新對象並不是相對的。你怎麼知道第一個人正在利用100%的資源?你只是看着你的任務管理器? – Arkantos